import * as Tooltip from '@radix-ui/react-tooltip' import { PermissionAction } from '@supabase/shared-types/out/constants' import { useState } from 'react' import ReactMarkdown from 'react-markdown' import { Alert, AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, Button, Collapsible, Form, IconAlertTriangle, IconCheck, IconChevronUp, Input, } from 'ui' import { useParams } from 'common' import { components } from 'data/api' import { useAuthConfigUpdateMutation } from 'data/auth/auth-config-update-mutation' import { useCustomDomainsQuery } from 'data/custom-domains/custom-domains-query' import { useCheckPermissions, useStore } from 'hooks' import { BASE_PATH } from 'lib/constants' import { ProviderCollapsibleClasses } from './AuthProvidersForm.constants' import { Provider } from './AuthProvidersForm.types' import FormField from './FormField' export interface ProviderFormProps { config: components['schemas']['GetGoTrueConfigResponse'] provider: Provider } const ProviderForm = ({ config, provider }: ProviderFormProps) => { const [open, setOpen] = useState(false) const { ui } = useStore() const { ref: projectRef } = useParams() const { mutate: updateAuthConfig, isLoading: isUpdatingConfig } = useAuthConfigUpdateMutation() const doubleNegativeKeys = ['MAILER_AUTOCONFIRM', 'SMS_AUTOCONFIRM'] const canUpdateConfig = useCheckPermissions(PermissionAction.UPDATE, 'custom_config_gotrue') const { data: customDomainData } = useCustomDomainsQuery({ projectRef }) const generateInitialValues = () => { const initialValues: { [x: string]: string } = {} // the config is already loaded through the parent component Object.keys(provider.properties).forEach((key) => { // When the key is a 'double negative' key, we must reverse the boolean before adding it to the form const isDoubleNegative = doubleNegativeKeys.includes(key) if (provider.title === 'SAML 2.0') { initialValues[key] = (config as any)[key] ?? false } else { initialValues[key] = isDoubleNegative ? !(config as any)[key] : (config as any)[key] ?? '' } }) return initialValues } const isSAMLEnabled: boolean = provider.title === 'SAML 2.0' && config && (config as any)['SAML_ENABLED'] // [Joel] Introduced as the new LinkedIn provider has a corresponding config var of LINKEDIN_OIDC const isLinkedInOIDCEnabled: boolean = provider.title === 'LinkedIn (OIDC)' && config && (config as any)['EXTERNAL_LINKEDIN_OIDC_ENABLED'] const isExternalProviderAndEnabled: boolean = config && (config as any)[`EXTERNAL_${provider?.title?.toUpperCase()}_ENABLED`] // [Joshen] Doing this check as SAML doesn't follow the same naming structure as the other provider options const isActive: boolean = isSAMLEnabled || isExternalProviderAndEnabled || isLinkedInOIDCEnabled const INITIAL_VALUES = generateInitialValues() const onSubmit = (values: any, { resetForm }: any) => { const payload = { ...values } // Format payload for the following checks: // 1. Convert all empty string values to null // 2. When the key is a 'double negative' key, we must reverse the boolean before the payload can be sent Object.keys(values).map((x: string) => { if (doubleNegativeKeys.includes(x)) payload[x] = !values[x] if (payload[x] === '') payload[x] = null }) updateAuthConfig( { projectRef: projectRef!, config: payload }, { onSuccess: () => { resetForm({ values: { ...values }, initialValues: { ...values } }) setOpen(false) ui.setNotification({ category: 'success', message: 'Successfully updated settings' }) }, } ) } return (
{({ handleReset, initialValues, values }: any) => { const noChanges = JSON.stringify(initialValues) === JSON.stringify(values) return (
{provider.title === 'LinkedIn (Deprecated)' && ( LinkedIn (Deprecated) Provider As of 1st August, LinkedIn has updated their OAuth API scopes. Please use the new LinkedIn provider below. Developers using this provider should move over to the new provider. Please refer to our [docs](/docs/pages/guides/auth/social-login/auth-linkedin) for more details. )} {/* TODO (Joel): Remove after 30th November when we disable the provider */} {provider.title === 'LinkedIn (Deprecated)' && Object.keys(provider.properties).map((x: string) => ( ))} {provider.title !== 'LinkedIn (Deprecated)' && Object.keys(provider.properties).map((x: string) => ( ))} {provider?.misc?.alert && ( {provider.misc.alert.description} )} {provider.misc.requiresRedirect && ( <> {provider.misc.helper} } /> )}
{!canUpdateConfig && (
You need additional permissions to update provider settings
)}
) }}
) } export default ProviderForm