import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' import { template } from 'lodash' import { Download, Loader2 } from 'lucide-react' import { useEffect, useMemo, useState } from 'react' import { toast } from 'sonner' import { Alert, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, Button, Card, CardContent, Switch, Tooltip, TooltipContent, TooltipTrigger, } from 'ui' import { PageSection, PageSectionContent, PageSectionMeta, PageSectionSummary, PageSectionTitle, } from 'ui-patterns' import { FormLayout } from 'ui-patterns/form/Layout/FormLayout' import { SupportLink } from '@/components/interfaces/Support/SupportLink' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { DocsButton } from '@/components/ui/DocsButton' import { InlineLinkClassName } from '@/components/ui/InlineLink' import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' import { useSSLEnforcementQuery } from '@/data/ssl-enforcement/ssl-enforcement-query' import { useSSLEnforcementUpdateMutation } from '@/data/ssl-enforcement/ssl-enforcement-update-mutation' import { useCustomContent } from '@/hooks/custom-content/useCustomContent' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { DOCS_URL } from '@/lib/constants' export const SSLConfiguration = () => { const { ref } = useParams() const { data: project } = useSelectedProjectQuery() const [isEnforced, setIsEnforced] = useState(false) const { data: settings } = useProjectSettingsV2Query({ projectRef: ref }) const { data: sslEnforcementConfiguration, isPending: isLoading, isSuccess, } = useSSLEnforcementQuery({ projectRef: ref, }) const { mutate: updateSSLEnforcement, isPending: isSubmitting } = useSSLEnforcementUpdateMutation( { onSuccess: () => { toast.success('Successfully updated SSL configuration') }, onError: (error) => { setIsEnforced(initialIsEnforced) toast.error(`Failed to update SSL enforcement: ${error.message}`) }, } ) const { can: canUpdateSSLEnforcement } = useAsyncCheckPermissions( PermissionAction.UPDATE, 'projects', { resource: { project_id: project?.id, }, } ) const initialIsEnforced = isSuccess ? sslEnforcementConfiguration.appliedSuccessfully && sslEnforcementConfiguration.currentConfig.database : false const hasAccessToSSLEnforcement = !( sslEnforcementConfiguration !== undefined && 'isNotAllowed' in sslEnforcementConfiguration && sslEnforcementConfiguration.isNotAllowed ) const env = process.env.NEXT_PUBLIC_ENVIRONMENT === 'prod' ? 'prod' : 'staging' const hasSSLCertificate = settings?.inserted_at !== undefined && new Date(settings.inserted_at) >= new Date('2021-04-30') const { sslCertificateUrl: sslCertificateUrlTemplate } = useCustomContent(['ssl:certificate_url']) const sslCertificateUrl = useMemo( () => template(sslCertificateUrlTemplate ?? '')({ env }), [sslCertificateUrlTemplate, env] ) useEffect(() => { if (!isLoading && sslEnforcementConfiguration) { setIsEnforced(initialIsEnforced) } }, [isLoading]) const toggleSSLEnforcement = async () => { if (!ref) return console.error('Project ref is required') setIsEnforced(!isEnforced) updateSSLEnforcement({ projectRef: ref, requestedConfig: { database: !isEnforced } }) } return ( SSL configuration
{(isLoading || isSubmitting) && ( )} {isSuccess && ( {/* [Joshen] Added div as tooltip is messing with data state property of toggle */}
{(!canUpdateSSLEnforcement || !hasAccessToSSLEnforcement) && ( {!canUpdateSSLEnforcement ? 'You need additional permissions to update SSL enforcement for your project' : !hasAccessToSSLEnforcement ? 'Your project does not have access to SSL enforcement' : undefined} )}
)}
Updating SSL enforcement involves a brief downtime A database restart is required for SSL enforcement changes to take place, and this involves a few minutes of downtime. Confirm to proceed now? Cancel {!isEnforced ? 'Enable SSL' : 'Disable SSL'}
{isSuccess && !sslEnforcementConfiguration?.appliedSuccessfully && ( Please try updating again, or contact{' '} support if this error persists )}
{!hasSSLCertificate ? ( } tooltip={{ content: { side: 'bottom', text: 'Projects before 15:08 (GMT+08), 29th April 2021 do not have SSL certificates installed', }, }} > Download certificate ) : ( )}
) }