Files
supabase/apps/studio/hooks/misc/useInboundBranding.ts
Saxon Fletcher e491182054 Auth flow improvements (#46967)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES/NO

## What kind of change does this PR introduce?

Bug fix, feature, docs update, ...

## What is the current behavior?

Please link any relevant issues here.

## What is the new behavior?

Feel free to include screenshots if it includes visual changes.

## Additional context

Add any other context or screenshots.


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

## Release Notes

* **New Features**
* Added “Continue with {provider}” sign-in and sign-up flows using
enabled external identity providers.
* Enabled inbound branding to focus a specific provider for customized
sign-in/sign-up experiences.

* **Improvements**
* Refined the sign-in options layout and “last used” tracking for
clearer authentication choices.
* Updated account identity/provider connection experiences (link/unlink
and management UI).

* **Bug Fixes**
  * Fixed hydration mismatches in sign-in and password-related layouts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-06-18 15:34:56 +08:00

62 lines
2.5 KiB
TypeScript

import { useRouter } from 'next/router'
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 router = useRouter()
const enabledProviders = useEnabledIdentityProviders()
const destinationId =
router.isReady && typeof router.query.destination === 'string'
? router.query.destination
: undefined
const focusId =
router.isReady && typeof router.query.method === 'string' ? router.query.method : undefined
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 }
}