mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Unregistered `custom:*` identity providers (e.g. white-label deployments' own OAuth providers) rendered their raw id — the account preferences "Sign-in methods" list showed something like `Custom:Acme` instead of `Acme`. `getProviderDisplay()` now derives a proper title-cased name from any `custom:*` id, so this works generically for every custom provider. **Changed:** - `getProviderDisplay()` derives a title-cased display name for unregistered `custom:*` providers (`custom:acme` → "Acme", `custom:my_provider` → "My Provider"), case-insensitively. Registered ones (e.g. `custom:openai` → ChatGPT) are unaffected. - `SignInWithCustom` reuses `getProviderDisplay()` instead of its own `formatProviderName`, which only stripped a lowercase `custom:` prefix — the display name also now flows into its error toast. - Added unit tests for the new fallback branch. ## To test - On a deployment with a custom provider (or by temporarily hardcoding an identity with `provider: 'custom:acme'` in `AccountIdentities`), check `/account/me` → Sign-in methods shows "Acme", not "Custom:Acme" - Unlink dialog/toast for that identity should also say "Acme" - Sign-in page with a custom provider configured should show "Continue with Acme" - `pnpm vitest run lib/external-identity-providers.test.ts` in `apps/studio` passes Addresses [FE-4193](https://linear.app/supabase/issue/FE-4193) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for unregistered custom identity providers. * Custom provider names are now displayed in a clearer, title-cased format with underscores converted to spaces. * Matching providers use the SAML icon while preserving their configured display names. * **Bug Fixes** * Improved sign-in error messages and button labels for custom providers. * Provider identifiers are now handled case-insensitively. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
83 lines
3.4 KiB
TypeScript
83 lines
3.4 KiB
TypeScript
import { afterEach, describe, expect, test, vi } from 'vitest'
|
|
|
|
import {
|
|
buildProviderAuthRedirect,
|
|
getIdentityProviderConfig,
|
|
getProviderDisplay,
|
|
normalizeIconPath,
|
|
} from './external-identity-providers'
|
|
|
|
describe('external identity providers', () => {
|
|
test('normalizes relative icon paths against the dashboard base path', () => {
|
|
expect(normalizeIconPath('/img/icons/github-icon.svg')).toBe('/img/icons/github-icon.svg')
|
|
expect(normalizeIconPath('img/icons/github-icon.svg')).toBe('/img/icons/github-icon.svg')
|
|
expect(normalizeIconPath('https://example.com/icon.svg')).toBe('https://example.com/icon.svg')
|
|
})
|
|
|
|
test('resolves static provider config by provider id or auth provider', () => {
|
|
expect(getIdentityProviderConfig('github')?.displayName).toBe('GitHub')
|
|
expect(getIdentityProviderConfig('unknown')).toBeUndefined()
|
|
})
|
|
|
|
test('returns display metadata for static, built-in, and fallback providers', () => {
|
|
expect(getProviderDisplay('github').displayName).toBe('GitHub')
|
|
expect(getProviderDisplay('email').displayName).toBe('Email')
|
|
expect(getProviderDisplay('sso:test').displayName).toBe('SSO')
|
|
expect(getProviderDisplay('my_provider').displayName).toBe('my provider')
|
|
})
|
|
|
|
test('derives a title-cased name for unregistered custom providers', () => {
|
|
expect(getProviderDisplay('custom:acme').displayName).toBe('Acme')
|
|
expect(getProviderDisplay('Custom:Acme').displayName).toBe('Acme')
|
|
expect(getProviderDisplay('custom:my_provider').displayName).toBe('My Provider')
|
|
expect(getProviderDisplay('custom:MY_PROVIDER').displayName).toBe('My Provider')
|
|
// registered custom providers keep their configured display name
|
|
expect(getProviderDisplay('custom:openai').displayName).toBe('ChatGPT')
|
|
})
|
|
|
|
test('marks static provider icons as monochrome but not built-in or fallback icons', () => {
|
|
expect(getProviderDisplay('github').hasMonochromeIcon).toBe(true)
|
|
expect(getProviderDisplay('email').hasMonochromeIcon).toBeUndefined()
|
|
expect(getProviderDisplay('sso:test').hasMonochromeIcon).toBeUndefined()
|
|
})
|
|
|
|
describe('buildProviderAuthRedirect', () => {
|
|
afterEach(() => {
|
|
vi.unstubAllEnvs()
|
|
})
|
|
|
|
test('builds the MFA-check URL against the configured site URL', () => {
|
|
vi.stubEnv('NEXT_PUBLIC_SITE_URL', 'https://supabase.com/dashboard')
|
|
|
|
expect(buildProviderAuthRedirect('github')).toBe(
|
|
'https://supabase.com/dashboard/sign-in-mfa?method=github'
|
|
)
|
|
})
|
|
|
|
test('URL-encodes custom provider ids in the method param', () => {
|
|
vi.stubEnv('NEXT_PUBLIC_SITE_URL', 'https://supabase.com/dashboard')
|
|
|
|
expect(buildProviderAuthRedirect('custom:example')).toBe(
|
|
'https://supabase.com/dashboard/sign-in-mfa?method=custom%3Aexample'
|
|
)
|
|
})
|
|
|
|
test('appends an encoded returnTo destination when provided', () => {
|
|
vi.stubEnv('NEXT_PUBLIC_SITE_URL', 'https://supabase.com/dashboard')
|
|
|
|
expect(buildProviderAuthRedirect('custom:example', '/account/me')).toBe(
|
|
'https://supabase.com/dashboard/sign-in-mfa?method=custom%3Aexample&returnTo=%2Faccount%2Fme'
|
|
)
|
|
})
|
|
|
|
test('uses the current origin on Vercel preview deployments', () => {
|
|
vi.stubEnv('NEXT_PUBLIC_VERCEL_ENV', 'preview')
|
|
vi.stubEnv('NEXT_PUBLIC_SITE_URL', 'https://supabase.com/dashboard')
|
|
|
|
expect(buildProviderAuthRedirect('github')).toBe(
|
|
`${location.origin}/sign-in-mfa?method=github`
|
|
)
|
|
})
|
|
})
|
|
})
|