Files
supabase/apps/studio/hooks/misc/useInboundBranding.ts
Danny WhiteandJoshen Lim ee3f78ff37 fix(studio): hide social sign-in after email sign-up (#49571)
## What kind of change does this PR introduce?

Bug fix. Resolves
[FE-4264](https://linear.app/supabase/issue/FE-4264/hide-social-sign-in-options-after-email-sign-up).

## What is the current behavior?

After a successful email and password sign-up, GitHub and ChatGPT
sign-in options remain visible even though they do not confirm or link
the new account.

The success state is presented in a bespoke `Alert` with verbose
copywriting.

## What is the new behavior?

The social sign-in options and divider are hidden after email sign-up
succeeds. The email confirmation message and link back to sign in remain
available.

The success state is presented in a standard `success` `Admonition` with
clearer copywriting.

| Before | After |
| --- | --- |
| <img width="2576" height="1700" alt="CleanShot 2026-08-26 at 13 47
41@2x"
src="https://github.com/user-attachments/assets/a29547b9-7949-4ff3-a1d4-db8bfb3beee6"
/> | <img width="2576" height="1704" alt="CleanShot 2026-08-26 at 13 47
00@2x"
src="https://github.com/user-attachments/assets/4f778571-74fe-4c20-b76e-a87e0391e4a9"
/> |

## To test

1. Open `/sign-up` and complete an email and password sign-up.
2. Confirm the success message is shown without the GitHub, ChatGPT, or
`or` options.
3. Open `/sign-in` and confirm GitHub and ChatGPT remain available
there.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added shared provider options across sign-in and sign-up flows,
including custom providers, external identity providers, and optional
SSO.
  - Added an SSO sign-in button that preserves the current page context.
- After successful email signup, alternative signup options are hidden
and confirmation messaging appears.
- **Bug Fixes**
- Improved signup form spacing, submission state, and animated password
guidance.
- **Tests**
- Added coverage for signup behavior across standard and
focused-provider configurations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-08-26 07:01:47 +00:00

56 lines
2.2 KiB
TypeScript

import { useParams } from 'common'
import { useMemo } from 'react'
import { useEnabledIdentityProviders } from './useEnabledIdentityProviders'
import { type ExternalIdentityProviderConfig } from '@/lib/external-identity-providers'
import { getDestinationById, type SignInDestination } from '@/lib/sign-in-destinations'
export type InboundBranding = {
/**
* Destination the user is signing in on the way to (e.g. the Supabase CLI), selected by the
* `destination` query param and resolved from the static `SIGN_IN_DESTINATIONS` registry. Brands
* the screen's logo and heading.
*/
destination?: SignInDestination
/**
* Enabled identity provider the inbound link asked us to focus on (the `method` param).
* When set, sign-in/sign-up render a trimmed-down screen offering only that provider's button.
*/
focusProvider?: ExternalIdentityProviderConfig
}
/**
* Reads the branding context for users arriving at sign-in/sign-up from somewhere else, such as the
* Supabase CLI. Both signals come straight from the URL: these screens render while the user is
* signed out, so branding can't depend on an authenticated API lookup. (The OAuth consent screen
* runs post-auth and brands itself dynamically by `auth_id` instead.)
*
* Destination and focused provider are independent: a destination brands the screen, and a focused
* provider trims the screen to a single button whether or not we know the destination.
*
* The focused provider must be enabled and visible in the current flow (`showOnSignIn` /
* `showOnSignUp`), otherwise there'd be no button to offer and we fall back to the full-option
* screen.
*/
export function useInboundBranding(flow: 'sign-in' | 'sign-up' = 'sign-in'): InboundBranding {
const enabledProviders = useEnabledIdentityProviders()
const { destination: destinationId, method: focusId } = useParams()
const focusProvider = useMemo(
() =>
focusId
? enabledProviders.find(
(provider) =>
focusId === provider.authProvider &&
(flow === 'sign-up' ? provider.showOnSignUp : provider.showOnSignIn)
)
: undefined,
[focusId, flow, enabledProviders]
)
const destination = getDestinationById(destinationId)
return { destination, focusProvider }
}