···661661 )}
662662 </CardContent>
663663 </Card>
664664+665665+ <div className="p-4 bg-muted/30 rounded-lg border-l-4 border-yellow-500/50">
666666+ <div className="flex items-start gap-2">
667667+ <AlertCircle className="w-4 h-4 text-yellow-600 dark:text-yellow-400 mt-0.5 flex-shrink-0" />
668668+ <div className="flex-1 space-y-1">
669669+ <p className="text-xs font-semibold text-yellow-600 dark:text-yellow-400">
670670+ Note about sites.wisp.place URLs
671671+ </p>
672672+ <p className="text-xs text-muted-foreground">
673673+ Complex sites hosted on <code className="px-1 py-0.5 bg-background rounded text-xs">sites.wisp.place</code> may have broken assets if they use absolute paths (e.g., <code className="px-1 py-0.5 bg-background rounded text-xs">/folder/script.js</code>) in CSS or JavaScript files. While HTML paths are automatically rewritten, CSS and JS files are served as-is. For best results, use a wisp.place subdomain or custom domain, or ensure your site uses relative paths.
674674+ </p>
675675+ </div>
676676+ </div>
677677+ </div>
664678 </TabsContent>
665679666680 {/* Domains Tab */}
···16041618 </div>
16051619 </div>
16061620 <p className="text-xs text-muted-foreground mt-2">
16071607- Some DNS providers may require you to use @ or leave it blank for the root domain
16211621+ Note: Some DNS providers (like Cloudflare) flatten CNAMEs to A records - this is fine and won't affect verification.
16081622 </p>
16091623 </div>
16101624 </div>
+19-3
src/lib/dns-verify.ts
···135135}
136136137137/**
138138- * Verify both TXT and CNAME records for a custom domain
138138+ * Verify custom domain using TXT record as authoritative proof
139139+ * CNAME check is optional/advisory - TXT record is sufficient for verification
140140+ *
141141+ * This approach works with CNAME flattening (e.g., Cloudflare) where the CNAME
142142+ * is resolved to A/AAAA records and won't be visible in DNS queries.
139143 */
140144export const verifyCustomDomain = async (
141145 domain: string,
142146 expectedDid: string,
143147 expectedHash: string
144148): Promise<VerificationResult> => {
149149+ // TXT record is authoritative - it proves ownership
145150 const txtResult = await verifyDomainOwnership(domain, expectedDid)
146151 if (!txtResult.verified) {
147152 return txtResult
148153 }
149154155155+ // CNAME check is advisory only - we still check it for logging/debugging
156156+ // but don't fail verification if it's missing (could be flattened)
150157 const cnameResult = await verifyCNAME(domain, expectedHash)
158158+159159+ // Log CNAME status for debugging, but don't fail on it
151160 if (!cnameResult.verified) {
152152- return cnameResult
161161+ console.log(`[DNS Verify] ⚠️ CNAME verification failed (may be flattened):`, cnameResult.error)
153162 }
154163155155- return { verified: true }
164164+ // TXT verification is sufficient
165165+ return {
166166+ verified: true,
167167+ found: {
168168+ txt: txtResult.found?.txt,
169169+ cname: cnameResult.found?.cname
170170+ }
171171+ }
156172}