Enforce verification of CNAME in first step of custom domain and sync custom domain instructions between dashboard and docs

This commit is contained in:
Joshen Lim committed 2023-01-19 14:05:39 +08:00
1 parent 46ef62bd74
commit bdb283664c
4 files changed
+61 -17

No files matched your search

@@ -89,6 +89,7 @@ const CustomDomainActivate = ({ projectRef, customDomain }: CustomDomainActivate
type="default"
onClick={onCancelCustomDomain}
loading={isDeleting}
disabled={isDeleting}
className="self-end"
>
Cancel
@@ -110,6 +111,7 @@ const CustomDomainActivate = ({ projectRef, customDomain }: CustomDomainActivate
/>
</svg>
}
disabled={isDeleting}
onClick={() => setIsActivateConfirmModalVisible(true)}
className="self-end"
>
@@ -37,7 +37,7 @@ const CustomDomainConfig = () => {
<section>
<FormHeader title="Custom Domains" description="Present a branded experience to your users" />
{data?.status === '0_no_hostname_configured' ? (
<CustomDomainsConfigureHostname projectRef={ref} />
<CustomDomainsConfigureHostname />
) : (
<Panel>
{isLoading && (
@@ -56,11 +56,11 @@ const CustomDomainVerify = ({ projectRef, customDomain, settings }: CustomDomain
<Panel.Content className="space-y-6">
<div>
<h4 className="text-scale-1200 mb-2">
Successfully added your custom domain{' '}
Configure TXT verification for your custom domain{' '}
<code className="text-sm">{customDomain.hostname}</code>
</h4>
<p className="text-sm text-scale-1100">
Set the following record(s) in your DNS provider, then click verify to confirm your
Set the following TXT record(s) in your DNS provider, then click verify to confirm your
control over the domain
</p>
<p className="text-sm text-scale-1100">
@@ -163,6 +163,16 @@ const CustomDomainVerify = ({ projectRef, customDomain, settings }: CustomDomain
</div>
)}
</div>
<div className="!mt-4">
<p className="text-sm text-scale-1000">
One of the records requires you to replace the CNAME record set up in the first step
with a TXT record.
</p>
<p className="text-sm text-scale-1000">
You'll be able to restore it back to the CNAME after the verification process has been
completed.
</p>
</div>
</Panel.Content>
<div className="border-t border-scale-400" />
@@ -181,6 +191,7 @@ const CustomDomainVerify = ({ projectRef, customDomain, settings }: CustomDomain
type="default"
onClick={onCancelCustomDomain}
loading={isDeleting}
disabled={isDeleting || isReverifyLoading}
className="self-end"
>
Cancel
@@ -189,6 +200,7 @@ const CustomDomainVerify = ({ projectRef, customDomain, settings }: CustomDomain
icon={<IconRefreshCw />}
onClick={onReverifyCustomDomain}
loading={isReverifyLoading}
disabled={isDeleting || isReverifyLoading}
className="self-end"
>
Verify
@@ -1,10 +1,10 @@
import Link from 'next/link'
import * as yup from 'yup'
import { Button, Form, IconExternalLink, Input } from 'ui'
import { observer } from 'mobx-react-lite'
import { Button, Form, IconExternalLink, Input } from 'ui'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { checkPermissions, useStore } from 'hooks'
import { checkPermissions, useParams, useProjectSettings, useStore } from 'hooks'
import {
FormActions,
FormPanel,
@@ -14,30 +14,48 @@ import {
} from 'components/ui/Forms'
import { useCustomDomainCreateMutation } from 'data/custom-domains/custom-domains-create-mutation'
const FORM_ID = 'custom-domains-form'
const schema = yup.object({
domain: yup.string().required('A value for your custom domain is required'),
})
export type CustomDomainsConfigureHostnameProps = {
projectRef?: string
}
const CustomDomainsConfigureHostname = ({ projectRef }: CustomDomainsConfigureHostnameProps) => {
const CustomDomainsConfigureHostname = () => {
const { ui } = useStore()
const canConfigureCustomDomain = checkPermissions(PermissionAction.UPDATE, 'projects')
const { ref } = useParams()
const { mutateAsync: createCustomDomain } = useCustomDomainCreateMutation()
const { services } = useProjectSettings(ref as string | undefined)
// Get the API service
const API_SERVICE_ID = 1
const apiService = services ? services.find((x: any) => x.app.id == API_SERVICE_ID) : {}
const endpoint = apiService?.app_config?.endpoint
const FORM_ID = 'custom-domains-form'
const canConfigureCustomDomain = checkPermissions(PermissionAction.UPDATE, 'projects')
const verifyCNAME = async (domain: string): Promise<boolean> => {
const res = await fetch(`https://1.1.1.1/dns-query?name=${domain}`, {
method: 'GET',
headers: { accept: 'application/dns-json' },
})
const verification = await res.json()
return verification.Status === 0
}
const onCreateCustomDomain = async (values: yup.InferType<typeof schema>) => {
if (!projectRef) {
throw new Error('Project ref is required')
if (!ref) throw new Error('Project ref is required')
const cnameVerified = await verifyCNAME(values.domain)
if (!cnameVerified) {
return ui.setNotification({
category: 'error',
duration: 4000,
message: `Your CNAME record for ${values.domain} has yet to be verified - please check back again in a bit.`,
})
}
try {
await createCustomDomain({
projectRef,
projectRef: ref,
customDomain: values.domain,
})
} catch (error: any) {
@@ -100,6 +118,18 @@ const CustomDomainsConfigureHostname = ({ projectRef }: CustomDomainsConfigureHo
/>
</FormSectionContent>
</FormSection>
<FormSection header={<FormSectionLabel>Configure a CNAME record</FormSectionLabel>}>
<p className="col-span-12 text-sm lg:col-span-7 leading-6">
Set up a CNAME record for{' '}
{values.domain ? (
<code className="text-xs">{values.domain}</code>
) : (
'your custom domain'
)}
, resolving to <code className="text-xs">{endpoint}</code>, with as low a TTL as
possible.
</p>
</FormSection>
</FormPanel>
</>
)