mirror of
https://github.com/supabase/supabase.git
synced 2026-10-17 15:19:08 +03:00
Enforce verification of CNAME in first step of custom domain and sync custom domain instructions between dashboard and docs
This commit is contained in:
1 parent
46ef62bd74
commit
bdb283664c
4 files changed
+61
-17
No files matched your search
+2
@@ -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"
|
||||
>
|
||||
|
||||
+1
-1
@@ -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 && (
|
||||
|
||||
+14
-2
@@ -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
|
||||
|
||||
+44
-14
@@ -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>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user