import * as React from 'react'; import { AuthenticatorMachineOptions, AmplifyUser, configureComponent, isFunction, } from '@aws-amplify/ui'; import { AuthenticatorProvider as Provider, useAuthenticator, UseAuthenticator, useAuthenticatorInitMachine, } from '@aws-amplify/ui-react-core'; import { VERSION } from '../../version'; import { useDeprecationWarning } from '../../hooks/useDeprecationWarning'; import { CustomComponentsContext, ComponentsProviderProps, } from './hooks/useCustomComponents'; import { Router, RouterProps } from './Router'; import { SetupTOTP } from './SetupTOTP'; import { SignIn } from './SignIn'; import { SignUp } from './SignUp'; import { ForceNewPassword } from './ForceNewPassword'; import { ResetPassword } from './ResetPassword'; import { defaultComponents } from './hooks/useCustomComponents/defaultComponents'; export type SignOut = UseAuthenticator['signOut']; export type AuthenticatorProps = Partial< AuthenticatorMachineOptions & ComponentsProviderProps & RouterProps & { children: | React.ReactNode | ((props: { signOut?: SignOut; user?: AmplifyUser }) => JSX.Element); } >; // `AuthenticatorInternal` exists to give access to the context returned via `useAuthenticator`, // which allows the `Authenticator` to just return `children` if a user is authenticated. // Once the `Provider` is removed from the `Authenticator` component and exported as // `AuthenticatorProvider`, this component should be renamed to `Authenticator`. export function AuthenticatorInternal({ children, className, components: customComponents, formFields, hideSignUp, initialState, loginMechanisms, passwordSettings, signUpAttributes, services, socialProviders, variation, }: AuthenticatorProps): JSX.Element { useDeprecationWarning({ message: 'The `passwordSettings` prop has been deprecated and will be removed in a future major version of Amplify UI.', shouldWarn: !!passwordSettings, }); const { route, signOut, user } = useAuthenticator( ({ route, signOut, user }) => [route, signOut, user] ); useAuthenticatorInitMachine({ initialState, loginMechanisms, services, signUpAttributes, socialProviders, formFields, }); const value = React.useMemo( () => ({ components: { ...defaultComponents, ...customComponents } }), [customComponents] ); const isAuthenticatedRoute = route === 'authenticated' || route === 'signOut'; if (isAuthenticatedRoute) { // `Authenticator` might not have user defined `children` for non SPA use cases. if (!children) { // @ts-ignore return null; } return ( <> {isFunction(children) ? children({ signOut, user }) // children is a render prop : children} ); } return ( ); } /** * [📖 Docs](https://ui.docs.amplify.aws/react/connected-components/authenticator) */ export function Authenticator(props: AuthenticatorProps): JSX.Element { React.useEffect(() => { configureComponent({ packageName: '@aws-amplify/ui-react', version: VERSION, }); }, []); return ( ); } Authenticator.Provider = Provider; Authenticator.ResetPassword = ResetPassword; Authenticator.SetupTOTP = SetupTOTP; Authenticator.SignIn = SignIn; Authenticator.SignUp = SignUp; Authenticator.ForceNewPassword = ForceNewPassword;