Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol. wisp.place

update dns to not necessitate cname verifcation in cases of cname flattening

Changed files
+34 -4
public
editor
src
+15 -1
public/editor/editor.tsx
···
)}
</CardContent>
</Card>
</TabsContent>
{/* Domains Tab */}
···
</div>
</div>
<p className="text-xs text-muted-foreground mt-2">
-
Some DNS providers may require you to use @ or leave it blank for the root domain
</p>
</div>
</div>
···
)}
</CardContent>
</Card>
+
+
<div className="p-4 bg-muted/30 rounded-lg border-l-4 border-yellow-500/50">
+
<div className="flex items-start gap-2">
+
<AlertCircle className="w-4 h-4 text-yellow-600 dark:text-yellow-400 mt-0.5 flex-shrink-0" />
+
<div className="flex-1 space-y-1">
+
<p className="text-xs font-semibold text-yellow-600 dark:text-yellow-400">
+
Note about sites.wisp.place URLs
+
</p>
+
<p className="text-xs text-muted-foreground">
+
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.
+
</p>
+
</div>
+
</div>
+
</div>
</TabsContent>
{/* Domains Tab */}
···
</div>
</div>
<p className="text-xs text-muted-foreground mt-2">
+
Note: Some DNS providers (like Cloudflare) flatten CNAMEs to A records - this is fine and won't affect verification.
</p>
</div>
</div>
+19 -3
src/lib/dns-verify.ts
···
}
/**
-
* Verify both TXT and CNAME records for a custom domain
*/
export const verifyCustomDomain = async (
domain: string,
expectedDid: string,
expectedHash: string
): Promise<VerificationResult> => {
const txtResult = await verifyDomainOwnership(domain, expectedDid)
if (!txtResult.verified) {
return txtResult
}
const cnameResult = await verifyCNAME(domain, expectedHash)
if (!cnameResult.verified) {
-
return cnameResult
}
-
return { verified: true }
}
···
}
/**
+
* Verify custom domain using TXT record as authoritative proof
+
* CNAME check is optional/advisory - TXT record is sufficient for verification
+
*
+
* This approach works with CNAME flattening (e.g., Cloudflare) where the CNAME
+
* is resolved to A/AAAA records and won't be visible in DNS queries.
*/
export const verifyCustomDomain = async (
domain: string,
expectedDid: string,
expectedHash: string
): Promise<VerificationResult> => {
+
// TXT record is authoritative - it proves ownership
const txtResult = await verifyDomainOwnership(domain, expectedDid)
if (!txtResult.verified) {
return txtResult
}
+
// CNAME check is advisory only - we still check it for logging/debugging
+
// but don't fail verification if it's missing (could be flattened)
const cnameResult = await verifyCNAME(domain, expectedHash)
+
+
// Log CNAME status for debugging, but don't fail on it
if (!cnameResult.verified) {
+
console.log(`[DNS Verify] ⚠️ CNAME verification failed (may be flattened):`, cnameResult.error)
}
+
// TXT verification is sufficient
+
return {
+
verified: true,
+
found: {
+
txt: txtResult.found?.txt,
+
cname: cnameResult.found?.cname
+
}
+
}
}