your personal website on atproto - mirror blento.app
at fixes 97 lines 2.6 kB view raw
1import { json } from '@sveltejs/kit'; 2import type { Did } from '@atcute/lexicons'; 3import { getClient, getRecord } from '$lib/atproto/methods'; 4 5export async function POST({ request, platform }) { 6 let body: { did: string; domain: string }; 7 try { 8 body = await request.json(); 9 } catch { 10 return json({ error: 'Invalid JSON body' }, { status: 400 }); 11 } 12 13 const { did, domain } = body; 14 15 if (!did || !domain) { 16 return json({ error: 'Missing required fields: did and domain' }, { status: 400 }); 17 } 18 19 // Validate domain format 20 if ( 21 !/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)+$/.test( 22 domain 23 ) 24 ) { 25 return json({ error: 'Invalid domain format' }, { status: 400 }); 26 } 27 28 // Check the user's site.standard.publication record 29 try { 30 const client = await getClient({ did: did as Did }); 31 const record = await getRecord({ 32 did: did as Did, 33 collection: 'site.standard.publication', 34 rkey: 'blento.self', 35 client 36 }); 37 38 const recordUrl = record?.value?.url; 39 const expectedUrl = `https://${domain}`; 40 41 if (recordUrl !== expectedUrl) { 42 return json( 43 { 44 error: `Publication record URL does not match. Expected "${expectedUrl}", got "${recordUrl || '(not set)'}".` 45 }, 46 { status: 400 } 47 ); 48 } 49 } catch { 50 return json( 51 { error: 'Could not read site.standard.publication record. Make sure it exists.' }, 52 { status: 400 } 53 ); 54 } 55 56 // Verify CNAME via DNS-over-HTTPS 57 try { 58 const dohUrl = `https://mozilla.cloudflare-dns.com/dns-query?name=${encodeURIComponent(domain)}&type=CNAME`; 59 const dnsRes = await fetch(dohUrl, { 60 headers: { Accept: 'application/dns-json' } 61 }); 62 const dnsData = await dnsRes.json(); 63 64 const cnameTarget = 'blento-proxy.fly.dev.'; 65 const cnameTargetNoDot = 'blento-proxy.fly.dev'; 66 67 const hasCname = dnsData.Answer?.some( 68 (answer: { type: number; data: string }) => 69 answer.type === 5 && (answer.data === cnameTarget || answer.data === cnameTargetNoDot) 70 ); 71 72 if (!hasCname) { 73 return json( 74 { 75 error: `CNAME record not found. Please set a CNAME for "${domain}" pointing to "blento-proxy.fly.dev".` 76 }, 77 { status: 400 } 78 ); 79 } 80 } catch { 81 return json({ error: 'Failed to verify DNS records.' }, { status: 500 }); 82 } 83 84 // Write to CUSTOM_DOMAINS KV 85 const kv = platform?.env?.CUSTOM_DOMAINS; 86 if (!kv) { 87 return json({ error: 'Domain storage is not available.' }, { status: 500 }); 88 } 89 90 try { 91 await kv.put(domain, did); 92 } catch { 93 return json({ error: 'Failed to save custom domain.' }, { status: 500 }); 94 } 95 96 return json({ success: true }); 97}