Files
FastGPT/projects/app/src/pageComponents/login/LoginForm/LoginForm.tsx
T
Archer bd966d479f fix: login secret (#6635)
* fix: login secret

* lock

* env template

* fix: ts

* fix: ts

* fix: ts
2026-03-25 14:45:38 +08:00

199 lines
5.7 KiB
TypeScript

import React, { useEffect, type Dispatch } from 'react';
import { FormControl, Flex, Input, Button, Box } from '@chakra-ui/react';
import { useForm } from 'react-hook-form';
import { LoginPageTypeEnum } from '@/web/support/user/login/constants';
import { postLogin, getPreLogin } from '@/web/support/user/api';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useTranslation } from 'next-i18next';
import FormLayout from './FormLayout';
import { useRequest } from '@fastgpt/web/hooks/useRequest';
import PolicyTip from './PolicyTip';
import { useSearchParams } from 'next/navigation';
import { UserErrEnum } from '@fastgpt/global/common/error/code/user';
import { useRouter } from 'next/router';
import { useMount } from 'ahooks';
import type { LangEnum } from '@fastgpt/global/common/i18n/type';
import type { LoginSuccessResponseType } from '@fastgpt/global/openapi/support/user/account/login/api';
interface Props {
setPageType: Dispatch<`${LoginPageTypeEnum}`>;
loginSuccess: (e: LoginSuccessResponseType) => void;
}
interface LoginFormType {
username: string;
password: string;
}
const LoginForm = ({ setPageType, loginSuccess }: Props) => {
const { t, i18n } = useTranslation();
const { feConfigs } = useSystemStore();
const query = useSearchParams();
const router = useRouter();
const {
register,
handleSubmit,
formState: { errors }
} = useForm<LoginFormType>();
const { runAsync: onclickLogin, loading: requesting } = useRequest(
async ({ username, password }: LoginFormType) => {
const { code } = await getPreLogin(username);
loginSuccess(
await postLogin({
username,
password,
code,
language: i18n.language as LangEnum
})
);
},
{
refreshDeps: [loginSuccess],
successToast: t('login:login_success'),
onError: (error: any) => {
// 密码错误,需要清空 query 参数
if (error.statusText === UserErrEnum.account_psw_error) {
router.replace(
router.pathname,
{
query: {
...router.query,
u: '',
p: ''
}
},
{
shallow: false
}
);
}
}
}
);
const isCommunityVersion = !!(feConfigs?.register_method && !feConfigs?.isPlus);
const placeholder = (() => {
if (isCommunityVersion) {
return t('login:use_root_login');
}
return [t('common:support.user.login.Username')]
.concat(
feConfigs?.login_method?.map((item) => {
switch (item) {
case 'email':
return t('common:support.user.login.Email');
case 'phone':
return t('common:support.user.login.Phone number');
}
}) ?? []
)
.join('/');
})();
useMount(() => {
const username = query.get('u');
const password = query.get('p');
if (username && password) {
onclickLogin({
username,
password
});
}
});
return (
<FormLayout setPageType={setPageType} pageType={LoginPageTypeEnum.passwordLogin}>
<Box
mt={8}
onKeyDown={(e) => {
if (e.key === 'Enter' && !e.shiftKey && !requesting) {
handleSubmit(onclickLogin)();
}
}}
>
<FormControl isInvalid={!!errors.username}>
<Input
bg={'myGray.50'}
size={'lg'}
placeholder={placeholder}
{...register('username', {
required: true
})}
></Input>
</FormControl>
<FormControl mt={7} isInvalid={!!errors.password}>
<Input
bg={'myGray.50'}
size={'lg'}
type={'password'}
placeholder={
isCommunityVersion
? t('login:root_password_placeholder')
: t('common:support.user.login.Password')
}
{...register('password', {
required: true,
maxLength: {
value: 60,
message: t('login:password_condition')
}
})}
></Input>
</FormControl>
<PolicyTip isCenter={false} />
<Button
type="submit"
my={[5, 7]}
w={'100%'}
size={['md', 'md']}
h={[10, 10]}
fontWeight={['medium', 'medium']}
colorScheme="blue"
isLoading={requesting}
onClick={handleSubmit(onclickLogin)}
>
{t('login:Login')}
</Button>
<Flex
align={'center'}
justifyContent={['flex-end', 'center']}
color={'primary.700'}
fontWeight={'medium'}
>
{feConfigs?.find_password_method && feConfigs.find_password_method.length > 0 && (
<Box
cursor={'pointer'}
_hover={{ textDecoration: 'underline' }}
onClick={() => setPageType('forgetPassword')}
fontSize="mini"
>
{t('login:forget_password')}
</Box>
)}
{feConfigs?.register_method && feConfigs.register_method.length > 0 && (
<Flex alignItems={'center'}>
<Box mx={3} h={'12px'} w={'1px'} bg={'myGray.250'}></Box>
<Box
cursor={'pointer'}
_hover={{ textDecoration: 'underline' }}
onClick={() => setPageType('register')}
fontSize="mini"
>
{t('login:register')}
</Box>
</Flex>
)}
</Flex>
</Box>
</FormLayout>
);
};
export default LoginForm;