your personal website on atproto - mirror
blento.app
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}