amplify-ui icon indicating copy to clipboard operation
amplify-ui copied to clipboard

Authenticator should have option to disable username/password flow

Open OperationalFallacy opened this issue 3 months ago • 5 comments

Before creating a new issue, please confirm:

On which framework/platform are you having an issue?

iOS, React

Which UI component?

Authenticator

How is your app built?

Next.js

What browsers are you seeing the problem on?

No response

Which region are you seeing the problem in?

No response

Please describe your bug.

I'd like to use only social logins in the app There is a way to disable self-registration in user pools https://github.com/aws-amplify/amplify-backend/issues/1313

Which solves a problem for the backend. However, on the front-end the Authenticator component still shows registration and login options with username and password. It doesn't have any props to hide it.

What's the expected behaviour?

An option to remove password sign and registration

    <Authenticator
      hidePasswordSignUp="true"

The only workaround for this is css hacks

[data-amplify-router-content] [data-amplify-authenticator-signin] .amplify-divider[data-label="or"] {
  display: none !important;
}

[data-amplify-router-content] [data-amplify-authenticator-signin] .amplify-flex fieldset {
  display: none !important;
}

[data-amplify-router-content] [data-amplify-authenticator-signin] .amplify-button[type="submit"] {
  display: none !important;
}

[data-amplify-router-content] [data-amplify-authenticator-signin] [data-amplify-footer] {
  display: none !important;
}

Help us reproduce the bug!

Normal amplify setup with usual <Authentictor> flows

Code Snippet

// Put your code below this line.

Console log output

No response

Additional information and screenshots

No response

OperationalFallacy avatar Sep 06 '25 16:09 OperationalFallacy

Hello @OperationalFallacy, thank you for raising this request. We will review this internally and provide you with an update.

Simone319 avatar Sep 08 '25 09:09 Simone319

Hi,

I wanted to check if there any progress on this. Can you point me at the specific package or code that creating this problem? I wanted to look how to patch it for my internal use.

OperationalFallacy avatar Oct 13 '25 13:10 OperationalFallacy

Hello @OperationalFallacy ,

We have not started with the implementation for this feature request yet.

Here's the SignIn implementation for Authenticator for React: https://github.com/aws-amplify/amplify-ui/blob/main/packages/react/src/components/Authenticator/SignIn/SignIn.tsx. We only supports customization of Header and Footer today.

Simone319 avatar Oct 15 '25 13:10 Simone319

had to monkey patch amplify-ui, build and use custom package :(

diff --git a/packages/react/src/components/Authenticator/FederatedSignIn/FederatedSignIn.tsx b/packages/react/src/components/Authenticator/FederatedSignIn/FederatedSignIn.tsx
index 588f4a33d..0b58b3cc1 100644
--- a/packages/react/src/components/Authenticator/FederatedSignIn/FederatedSignIn.tsx
+++ b/packages/react/src/components/Authenticator/FederatedSignIn/FederatedSignIn.tsx
@@ -11,7 +11,13 @@ import { FederatedSignInButton } from './FederatedSignInButtons';
 
 const { getSignInWithFederationText, getOrText } = authenticatorTextUtil;
 
-export function FederatedSignIn(): React.JSX.Element {
+export interface FederatedSignInProps {
+  showDivider?: boolean;
+}
+
+export function FederatedSignIn({
+  showDivider = true,
+}: FederatedSignInProps): React.JSX.Element {
   const { route, socialProviders } = useAuthenticator(
     ({ route, socialProviders }) => [route, socialProviders]
   );
@@ -73,7 +79,7 @@ export function FederatedSignIn(): React.JSX.Element {
         }
       })}
 
-      <Divider size="small" label={getOrText()} />
+      {showDivider && <Divider size="small" label={getOrText()} />}
     </Flex>
   );
 }
diff --git a/packages/react/src/components/Authenticator/SignIn/SignIn.tsx b/packages/react/src/components/Authenticator/SignIn/SignIn.tsx
index d0b100304..99146384a 100644
--- a/packages/react/src/components/Authenticator/SignIn/SignIn.tsx
+++ b/packages/react/src/components/Authenticator/SignIn/SignIn.tsx
@@ -10,7 +10,7 @@ import { useAuthenticator } from '@aws-amplify/ui-react-core';
 import { useCustomComponents } from '../hooks/useCustomComponents';
 import { useFormHandlers } from '../hooks/useFormHandlers';
 import { RemoteErrorMessage } from '../shared/RemoteErrorMessage';
-import { FormFields } from '../shared/FormFields';
+import { FormFields as DefaultFormFields } from '../shared/FormFields';
 
 const { getSignInText, getSigningInText, getForgotPasswordText } =
   authenticatorTextUtil;
@@ -22,44 +22,58 @@ export function SignIn(): React.JSX.Element {
   const {
     components: {
       // @ts-ignore
-      SignIn: { Header = SignIn.Header, Footer = SignIn.Footer },
+      SignIn: {
+        Header = SignIn.Header,
+        Footer = SignIn.Footer,
+        FormFields = SignIn.FormFields,
+      },
     },
   } = useCustomComponents();
 
+  // Check if FormFields is overridden to return null (social-only mode)
+  const isFormFieldsDisabled =
+    FormFields &&
+    typeof FormFields === 'function' &&
+    (FormFields as Function).toString().includes('null');
+
   return (
     <View>
       <Header />
 
-      <form
-        data-amplify-form=""
-        data-amplify-authenticator-signin=""
-        method="post"
-        onSubmit={handleSubmit}
-        onChange={handleChange}
-      >
-        <FederatedSignIn />
-        <Flex direction="column">
-          <Flex as="fieldset" direction="column" isDisabled={isPending}>
-            <VisuallyHidden>
-              <legend>{getSignInText()}</legend>
-            </VisuallyHidden>
-            <FormFields />
-          </Flex>
+      {isFormFieldsDisabled ? (
+        <FederatedSignIn showDivider={true} />
+      ) : (
+        <form
+          data-amplify-form=""
+          data-amplify-authenticator-signin=""
+          method="post"
+          onSubmit={handleSubmit}
+          onChange={handleChange}
+        >
+          <FederatedSignIn />
+          <Flex direction="column">
+            <Flex as="fieldset" direction="column" isDisabled={isPending}>
+              <VisuallyHidden>
+                <legend>{getSignInText()}</legend>
+              </VisuallyHidden>
+              <FormFields />
+            </Flex>
 
-          <RemoteErrorMessage />
+            <RemoteErrorMessage />
 
-          <Button
-            isDisabled={isPending}
-            type="submit"
-            variation="primary"
-            isLoading={isPending}
-            loadingText={getSigningInText()}
-          >
-            {getSignInText()}
-          </Button>
-          <Footer />
-        </Flex>
-      </form>
+            <Button
+              isDisabled={isPending}
+              type="submit"
+              variation="primary"
+              isLoading={isPending}
+              loadingText={getSigningInText()}
+            >
+              {getSignInText()}
+            </Button>
+          </Flex>
+        </form>
+      )}
+      <Footer />
     </View>
   );
 }
@@ -79,6 +93,9 @@ const DefaultFooter = () => {
 };
 
 SignIn.Footer = DefaultFooter;
+SignIn.FormFields = function FormFields() {
+  return <DefaultFormFields />;
+};
 SignIn.Header = function Header(): React.JSX.Element {
   // @ts-ignore
   return null;
diff --git a/packages/react/src/components/Authenticator/SignUp/SignUp.tsx b/packages/react/src/components/Authenticator/SignUp/SignUp.tsx
index 6869b3715..462a68679 100644
--- a/packages/react/src/components/Authenticator/SignUp/SignUp.tsx
+++ b/packages/react/src/components/Authenticator/SignUp/SignUp.tsx
@@ -31,39 +31,49 @@ export function SignUp(): React.JSX.Element {
     },
   } = useCustomComponents();
 
+  // Check if FormFields is overridden to return null (social-only mode)
+  const isFormFieldsDisabled =
+    FormFields &&
+    typeof FormFields === 'function' &&
+    (FormFields as Function).toString().includes('null');
+
   return (
     <View>
       <Header />
 
-      <form
-        data-amplify-form=""
-        data-amplify-authenticator-signup=""
-        method="post"
-        onChange={handleChange}
-        onSubmit={handleSubmit}
-        onBlur={handleBlur}
-      >
-        <FederatedSignIn />
+      {isFormFieldsDisabled ? (
+        <FederatedSignIn showDivider={false} />
+      ) : (
+        <form
+          data-amplify-form=""
+          data-amplify-authenticator-signup=""
+          method="post"
+          onChange={handleChange}
+          onSubmit={handleSubmit}
+          onBlur={handleBlur}
+        >
+          <FederatedSignIn showDivider={true} />
 
-        <Flex as="fieldset" direction="column" isDisabled={isPending}>
-          <Flex direction="column">
-            <FormFields />
-            <RemoteErrorMessage />
-          </Flex>
+          <Flex as="fieldset" direction="column" isDisabled={isPending}>
+            <Flex direction="column">
+              <FormFields />
+              <RemoteErrorMessage />
+            </Flex>
 
-          <Button
-            isDisabled={hasValidationErrors || isPending}
-            isFullWidth
-            type="submit"
-            variation="primary"
-            isLoading={isPending}
-            loadingText={getCreatingAccountText()}
-          >
-            {getCreateAccountText()}
-          </Button>
-          <Footer />
-        </Flex>
-      </form>
+            <Button
+              isDisabled={hasValidationErrors || isPending}
+              isFullWidth
+              type="submit"
+              variation="primary"
+              isLoading={isPending}
+              loadingText={getCreatingAccountText()}
+            >
+              {getCreateAccountText()}
+            </Button>
+          </Flex>
+        </form>
+      )}
+      <Footer />
     </View>
   );
 }
diff --git a/packages/ui/src/helpers/authenticator/getRoute.ts b/packages/ui/src/helpers/authenticator/getRoute.ts
index 8d88b5c5a..337175b03 100644
--- a/packages/ui/src/helpers/authenticator/getRoute.ts
+++ b/packages/ui/src/helpers/authenticator/getRoute.ts
@@ -23,6 +23,12 @@ export const getRoute = (
     if (state.matches('signInActor')) {
       return 'signIn';
     }
+    if (state.matches('signUpActor.runActor')) {
+      return 'signUp';
+    }
+    if (state.matches('signInActor.runActor')) {
+      return 'signIn';
+    }
   }
 
   switch (true) {

Then in Authenticator

<Authenticator
      initialState={InitialAuth}
      signUpAttributes={["name"]}
      hideSignUp={HideSignUp}
      variation="modal"
      components={{
        SignIn: {
          // @ts-ignore - FormFields override for social-only auth
          FormFields: (() => null) as any,
          Footer() {
            return (
...   
           );
          }
        },
        SignUp: {
          // @ts-ignore - FormFields override for social-only auth
          FormFields: (() => null) as any,
          Footer() {
...

A hack but it worked

Image

OperationalFallacy avatar Oct 15 '25 15:10 OperationalFallacy

Thanks for creating the change. Glad that it is working for you.

Would you like to open a PR with the change you're made to the amplify-ui repo? I'd be happy to help review and merge it so that it's available to other amplify users.

Nevertheless, we will still look into implementing it on amplify end.

Simone319 avatar Oct 16 '25 14:10 Simone319