mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-01 18:52:20 +08:00
114 lines
3.4 KiB
TypeScript
114 lines
3.4 KiB
TypeScript
/**
|
|
* This file is part of the NocoBase (R) project.
|
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
* Authors: NocoBase Team.
|
|
*
|
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
*/
|
|
|
|
import { ISchema } from '@formily/react';
|
|
import { SchemaComponent, useAPIClient, useCurrentUserContext } from '@nocobase/client';
|
|
import React, { useCallback } from 'react';
|
|
import { useAuthTranslation } from '../locale';
|
|
import { useNavigate, useSearchParams } from 'react-router-dom';
|
|
import { useForm } from '@formily/react';
|
|
import { useSignUpForms } from '../pages';
|
|
import { Authenticator } from '../authenticator';
|
|
|
|
export function useRedirect(next = '/admin') {
|
|
const navigate = useNavigate();
|
|
const [searchParams] = useSearchParams();
|
|
return useCallback(() => {
|
|
navigate(searchParams.get('redirect') || '/admin', { replace: true });
|
|
}, [navigate, searchParams]);
|
|
}
|
|
|
|
export const useSignIn = (authenticator: string) => {
|
|
const form = useForm();
|
|
const api = useAPIClient();
|
|
const redirect = useRedirect();
|
|
const { refreshAsync } = useCurrentUserContext();
|
|
return {
|
|
async run() {
|
|
await form.submit();
|
|
await api.auth.signIn(form.values, authenticator);
|
|
await refreshAsync();
|
|
redirect();
|
|
},
|
|
};
|
|
};
|
|
|
|
const passwordForm: ISchema = {
|
|
type: 'object',
|
|
name: 'passwordForm',
|
|
'x-component': 'FormV2',
|
|
properties: {
|
|
account: {
|
|
type: 'string',
|
|
'x-component': 'Input',
|
|
'x-validator': `{{(value) => {
|
|
if (!value) {
|
|
return t("Please enter your username or email");
|
|
}
|
|
if (value.includes('@')) {
|
|
if (!/^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$/.test(value)) {
|
|
return t("Please enter a valid email");
|
|
}
|
|
} else {
|
|
return /^[^@.<>"'/]{1,50}$/.test(value) || t("Please enter a valid username");
|
|
}
|
|
}}}`,
|
|
'x-decorator': 'FormItem',
|
|
'x-component-props': { placeholder: '{{t("Username/Email")}}', style: {} },
|
|
},
|
|
password: {
|
|
type: 'string',
|
|
'x-component': 'Password',
|
|
required: true,
|
|
'x-decorator': 'FormItem',
|
|
'x-component-props': { placeholder: '{{t("Password")}}', style: {} },
|
|
},
|
|
actions: {
|
|
type: 'void',
|
|
'x-component': 'div',
|
|
properties: {
|
|
submit: {
|
|
title: '{{t("Sign in")}}',
|
|
type: 'void',
|
|
'x-component': 'Action',
|
|
'x-component-props': {
|
|
htmlType: 'submit',
|
|
block: true,
|
|
type: 'primary',
|
|
useAction: `{{ useBasicSignIn }}`,
|
|
style: { width: '100%' },
|
|
},
|
|
},
|
|
},
|
|
},
|
|
signUp: {
|
|
type: 'void',
|
|
'x-component': 'Link',
|
|
'x-component-props': {
|
|
to: '{{ signUpLink }}',
|
|
},
|
|
'x-content': '{{t("Create an account")}}',
|
|
'x-visible': '{{ allowSignUp }}',
|
|
},
|
|
},
|
|
};
|
|
export const SignInForm = (props: { authenticator: Authenticator }) => {
|
|
const { t } = useAuthTranslation();
|
|
const authenticator = props.authenticator;
|
|
const { authType, name, options } = authenticator;
|
|
const signUpPages = useSignUpForms();
|
|
const allowSignUp = signUpPages[authType] && options?.allowSignUp ? true : false;
|
|
const signUpLink = `/signup?name=${name}`;
|
|
|
|
const useBasicSignIn = () => {
|
|
return useSignIn(name);
|
|
};
|
|
return <SchemaComponent schema={passwordForm} scope={{ useBasicSignIn, allowSignUp, signUpLink, t }} />;
|
|
};
|