mirror of
https://github.com/supabase/supabase.git
synced 2026-06-24 09:55:17 +08:00
## 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>
117 lines
3.6 KiB
TypeScript
117 lines
3.6 KiB
TypeScript
import { BASE_PATH } from './constants'
|
|
|
|
export type ExternalIdentityProviderConfig = {
|
|
id: string
|
|
authProvider: string
|
|
displayName: string
|
|
iconPath: string
|
|
scopes?: string
|
|
showOnSignIn: boolean
|
|
showOnSignUp: boolean
|
|
showInAccountPreferences: boolean
|
|
}
|
|
|
|
export type IdentityProviderDisplay = {
|
|
id: string
|
|
displayName: string
|
|
iconPath: string
|
|
/** The icon is a single-color mark that should be tinted to the theme's foreground color. */
|
|
hasMonochromeIcon?: boolean
|
|
}
|
|
|
|
const BUILT_IN_IDENTITY_PROVIDERS: Record<string, IdentityProviderDisplay> = {
|
|
email: {
|
|
id: 'email',
|
|
displayName: 'Email',
|
|
iconPath: `${BASE_PATH}/img/icons/email-icon2.svg`,
|
|
},
|
|
}
|
|
|
|
// Statically supported identity providers. To add a new one, declare its config here, gate its
|
|
// visibility behind a `dashboard_auth:sign_in_with_*` feature flag in `useEnabledIdentityProviders`,
|
|
// and add the matching flag to `packages/common/enabled-features/enabled-features.json`.
|
|
export const GITHUB_IDENTITY_PROVIDER: ExternalIdentityProviderConfig = {
|
|
id: 'github',
|
|
authProvider: 'github',
|
|
displayName: 'GitHub',
|
|
iconPath: '/img/icons/github-icon.svg',
|
|
showOnSignIn: true,
|
|
showOnSignUp: true,
|
|
showInAccountPreferences: false,
|
|
}
|
|
|
|
// Registry of every known provider, independent of which are currently enabled. Used for config and
|
|
// display lookups (e.g. resolving the provider that a mid-flow interstitial was reached with).
|
|
const IDENTITY_PROVIDERS: ExternalIdentityProviderConfig[] = [GITHUB_IDENTITY_PROVIDER]
|
|
|
|
export function normalizeIconPath(iconPath: string): string {
|
|
if (
|
|
iconPath.startsWith('http://') ||
|
|
iconPath.startsWith('https://') ||
|
|
iconPath.startsWith('/')
|
|
) {
|
|
return iconPath.startsWith('/') ? `${BASE_PATH}${iconPath}` : iconPath
|
|
}
|
|
|
|
return `${BASE_PATH}/${iconPath}`
|
|
}
|
|
|
|
export function getProviderDisplay(provider: string): IdentityProviderDisplay {
|
|
const config = IDENTITY_PROVIDERS.find(
|
|
({ id, authProvider }) => provider === id || provider === authProvider
|
|
)
|
|
|
|
if (config) {
|
|
return {
|
|
id: config.id,
|
|
displayName: config.displayName,
|
|
iconPath: normalizeIconPath(config.iconPath),
|
|
hasMonochromeIcon: true,
|
|
}
|
|
}
|
|
|
|
if (provider.startsWith('sso')) {
|
|
return {
|
|
id: provider,
|
|
displayName: 'SSO',
|
|
iconPath: `${BASE_PATH}/img/icons/saml-icon.svg`,
|
|
}
|
|
}
|
|
|
|
return (
|
|
BUILT_IN_IDENTITY_PROVIDERS[provider] ?? {
|
|
id: provider,
|
|
displayName: provider.replaceAll('_', ' '),
|
|
iconPath: `${BASE_PATH}/img/icons/saml-icon.svg`,
|
|
}
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Builds the absolute URL an external provider's OAuth flow redirects back to: the MFA-check page
|
|
* (`/sign-in-mfa`), tagged with the provider id as the sign-in method and an optional `returnTo`
|
|
* destination. Callers should pass the result through `buildPathWithParams` to preserve the current
|
|
* location's search params across the OAuth round-trip.
|
|
*/
|
|
export function buildProviderAuthRedirect(providerId: string, returnTo?: string): string {
|
|
const origin =
|
|
typeof window !== 'undefined' && process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview'
|
|
? window.location.origin
|
|
: process.env.NEXT_PUBLIC_SITE_URL
|
|
|
|
const params = new URLSearchParams({ method: providerId })
|
|
if (returnTo) params.set('returnTo', returnTo)
|
|
|
|
return `${origin}${BASE_PATH}/sign-in-mfa?${params.toString()}`
|
|
}
|
|
|
|
export function getIdentityProviderConfig(
|
|
provider: string | undefined
|
|
): ExternalIdentityProviderConfig | undefined {
|
|
if (!provider) return undefined
|
|
|
|
return IDENTITY_PROVIDERS.find(
|
|
({ id, authProvider }) => provider === id || provider === authProvider
|
|
)
|
|
}
|