@@ -5,6 +5,7 @@ import { useEffect, useState } from "react";
55import { toast } from "sonner" ;
66import { useDashboardContext } from "@/app/(org)/dashboard/Contexts" ;
77import type { DomainConfig , DomainVerification } from "./types" ;
8+ import { parse } from "tldts" ;
89
910interface VerifyStepProps {
1011 domain : string ;
@@ -54,14 +55,25 @@ const VerifyStep = ({
5455 return [ ] ;
5556 } ;
5657
57- const isSubdomain = ( domain : string ) : boolean => {
58- domain = domain . replace ( / ^ h t t p s ? : \/ \/ / , "" ) ;
59- domain = domain . split ( "/" ) [ 0 ] ?? "" ;
60- if ( ! domain ) return false ;
61- const parts : string [ ] = domain . split ( "." ) ;
62- return parts . length > 2 ;
58+ const isSubdomain = ( raw : string ) : boolean => {
59+ // Normalize and extract host (no scheme, path, port, or trailing dot)
60+ const input =
61+ raw
62+ . trim ( )
63+ . replace ( / ^ h t t p s ? : \/ \/ / i, "" )
64+ . split ( "/" ) [ 0 ] ?? "" ;
65+ if ( ! input ) return false ;
66+ const host = ( input . replace ( / \. $ / , "" ) . split ( ":" ) [ 0 ] || "" ) . toLowerCase ( ) ;
67+ try {
68+ // Prefer PSL-backed parsing for correctness (e.g., co.uk, com.au)
69+ const { subdomain } = parse ( host ) ;
70+ return Boolean ( subdomain ) ;
71+ } catch {
72+ // Fallback: conservative heuristic
73+ const parts = host . split ( "." ) ;
74+ return parts . length > 2 ;
75+ }
6376 } ;
64-
6577 const recommendedAValues = getRecommendedAValues ( ) ;
6678
6779 // Check if DNS records are already correctly configured
@@ -72,7 +84,7 @@ const VerifyStep = ({
7284 recommendedCnames . length > 0 &&
7385 recommendedCnames . some ( ( rec ) => currentCnames . includes ( rec . value ) ) ;
7486 const showARecord =
75- recommendedARecord && ! aRecordConfigured && ! isSubdomain ( domain ) ;
87+ recommendedAValues . length > 0 && ! aRecordConfigured && ! isSubdomain ( domain ) ;
7688 const showCNAMERecord = hasRecommendedCNAME && ! cnameConfigured ;
7789 const showTXTRecord = hasTXTVerification && ! isVerified ;
7890
0 commit comments