index.tsx123 lines · main
| 1 | import { useParams } from 'common' |
| 2 | import { ExternalLink } from 'lucide-react' |
| 3 | import Link from 'next/link' |
| 4 | import { Alert, AlertDescription, AlertTitle, Button, WarningIcon } from 'ui' |
| 5 | import { |
| 6 | PageSection, |
| 7 | PageSectionContent, |
| 8 | PageSectionDescription, |
| 9 | PageSectionMeta, |
| 10 | PageSectionSummary, |
| 11 | PageSectionTitle, |
| 12 | } from 'ui-patterns/PageSection' |
| 13 | |
| 14 | import { getPhoneProviderValidationSchema, PROVIDERS_SCHEMAS } from '../AuthProvidersFormValidation' |
| 15 | import type { Provider } from './AuthProvidersForm.types' |
| 16 | import { ProviderForm } from './ProviderForm' |
| 17 | import AlertError from '@/components/ui/AlertError' |
| 18 | import { ResourceList } from '@/components/ui/Resource/ResourceList' |
| 19 | import { HorizontalShimmerWithIcon } from '@/components/ui/Shimmers' |
| 20 | import { useAuthConfigQuery } from '@/data/auth/auth-config-query' |
| 21 | |
| 22 | export const AuthProvidersForm = () => { |
| 23 | const { ref: projectRef } = useParams() |
| 24 | const { |
| 25 | data: authConfig, |
| 26 | error: authConfigError, |
| 27 | isPending: isLoading, |
| 28 | isError, |
| 29 | isSuccess, |
| 30 | } = useAuthConfigQuery({ projectRef }) |
| 31 | |
| 32 | return ( |
| 33 | <PageSection> |
| 34 | <PageSectionMeta> |
| 35 | <PageSectionSummary> |
| 36 | <PageSectionTitle>Auth Providers</PageSectionTitle> |
| 37 | <PageSectionDescription> |
| 38 | Authenticate your users through a suite of providers and login methods |
| 39 | </PageSectionDescription> |
| 40 | </PageSectionSummary> |
| 41 | </PageSectionMeta> |
| 42 | <PageSectionContent> |
| 43 | {isError ? ( |
| 44 | <AlertError |
| 45 | error={authConfigError} |
| 46 | subject="Failed to retrieve auth configuration for hooks" |
| 47 | /> |
| 48 | ) : ( |
| 49 | <div className="-space-y-px"> |
| 50 | {authConfig?.EXTERNAL_EMAIL_ENABLED && authConfig?.MAILER_OTP_EXP > 3600 && ( |
| 51 | <Alert className="flex w-full items-center justify-between my-3" variant="warning"> |
| 52 | <WarningIcon /> |
| 53 | <div> |
| 54 | <AlertTitle>OTP expiry exceeds recommended threshold</AlertTitle> |
| 55 | <AlertDescription className="flex flex-col gap-y-3"> |
| 56 | <p> |
| 57 | We have detected that you have enabled the email provider with the OTP expiry |
| 58 | set to more than an hour. It is recommended to set this value to less than an |
| 59 | hour. |
| 60 | </p> |
| 61 | <Button asChild type="default" className="w-min" icon={<ExternalLink />}> |
| 62 | <Link href="https://supabase.com/docs/guides/platform/going-into-prod#security"> |
| 63 | View security recommendations |
| 64 | </Link> |
| 65 | </Button> |
| 66 | </AlertDescription> |
| 67 | </div> |
| 68 | </Alert> |
| 69 | )} |
| 70 | |
| 71 | <ResourceList> |
| 72 | {isLoading && |
| 73 | PROVIDERS_SCHEMAS.map((provider) => ( |
| 74 | <div |
| 75 | key={`provider_${provider.title}`} |
| 76 | className="py-4 px-6 border-b last:border-b-none" |
| 77 | > |
| 78 | <HorizontalShimmerWithIcon /> |
| 79 | </div> |
| 80 | ))} |
| 81 | {isSuccess && |
| 82 | PROVIDERS_SCHEMAS.map((provider) => { |
| 83 | const providerSchema = |
| 84 | provider.title === 'Phone' |
| 85 | ? { |
| 86 | ...provider, |
| 87 | validationSchema: getPhoneProviderValidationSchema(authConfig), |
| 88 | } |
| 89 | : provider |
| 90 | let isActive = false |
| 91 | if (providerSchema.title === 'SAML 2.0') { |
| 92 | isActive = authConfig && (authConfig as any)['SAML_ENABLED'] |
| 93 | } else if (providerSchema.title === 'LinkedIn (OIDC)') { |
| 94 | isActive = authConfig && (authConfig as any)['EXTERNAL_LINKEDIN_OIDC_ENABLED'] |
| 95 | } else if (providerSchema.title === 'Slack (OIDC)') { |
| 96 | isActive = authConfig && (authConfig as any)['EXTERNAL_SLACK_OIDC_ENABLED'] |
| 97 | } else if (providerSchema.title.includes('Web3')) { |
| 98 | isActive = authConfig && (authConfig as any)['EXTERNAL_WEB3_SOLANA_ENABLED'] |
| 99 | } else if (providerSchema.title.includes('X / Twitter (OAuth 2.0)')) { |
| 100 | isActive = authConfig && (authConfig as any)['EXTERNAL_X_ENABLED'] |
| 101 | } else if (providerSchema.title === 'Twitter (Deprecated)') { |
| 102 | isActive = authConfig && (authConfig as any)['EXTERNAL_TWITTER_ENABLED'] |
| 103 | } else { |
| 104 | isActive = |
| 105 | authConfig && |
| 106 | (authConfig as any)[`EXTERNAL_${providerSchema.title.toUpperCase()}_ENABLED`] |
| 107 | } |
| 108 | return ( |
| 109 | <ProviderForm |
| 110 | key={`provider_${providerSchema.title}`} |
| 111 | config={authConfig!} |
| 112 | provider={providerSchema as unknown as Provider} |
| 113 | isActive={isActive} |
| 114 | /> |
| 115 | ) |
| 116 | })} |
| 117 | </ResourceList> |
| 118 | </div> |
| 119 | )} |
| 120 | </PageSectionContent> |
| 121 | </PageSection> |
| 122 | ) |
| 123 | } |