[WIP] A (somewhat barebones) atproto app for creating custom sites without hosting!
1import root from "./routes/root.ts";
2import user from "./routes/user.ts";
3import backfill from "./backfill/index.ts";
4import { clearCookies, PORT, ROOT_DOMAIN, SUBDOMAIN_REGEX } from "./utils.ts";
5
6const db = await backfill;
7
8Deno.serve({ port: PORT, hostname: ROOT_DOMAIN }, async (req) => {
9 const reqUrl = new URL(req.url);
10 const subdomain = reqUrl.hostname.match(SUBDOMAIN_REGEX)?.at(0)?.split(".");
11
12 // redirect ROOT_DOMAIN => www.ROOT_DOMAIN
13 if (!subdomain) {
14 const redirUrl = new URL(reqUrl.toString());
15 redirUrl.host = "www." + redirUrl.host;
16 return new Response(`Redirecting to ${redirUrl.toString()}`, {
17 status: 308,
18 headers: {
19 Location: redirUrl.toString(),
20 },
21 });
22 }
23
24 if (subdomain.length === 1 && subdomain[0] === "www") return root(req);
25
26 // did:plc example: `sjkdgfjk.did-plc.ROOT_DOMAIN`
27 // did:web example: `vielle.dev.did-web.ROOT_DOMAIN
28 // last segment must be did-plc or did-web
29 const isDidSubdomain = !!subdomain.at(-1)?.match(/^did-(web|plc)+$/gm);
30 // ex: vielle.dev.ROOT_DOMAIN
31 // cannot contain hyphen in top level domain
32 const isHandleSubdomain = !isDidSubdomain && subdomain.length > 1;
33
34 if (isDidSubdomain || isHandleSubdomain) {
35 const res: Response = await user(
36 db,
37 req,
38 isDidSubdomain
39 ? {
40 did: `did:${subdomain.at(-1) === "did-plc" ? "plc" : "web"}:${subdomain
41 .slice(0, -1)
42 .join(".")}`,
43 }
44 : {
45 handle: subdomain.join(".") as `${string}.${string}`,
46 }
47 );
48 return new Response(res.body, {
49 ...res,
50 headers: {
51 ...res.headers,
52 ...clearCookies(req),
53 },
54 });
55 }
56
57 return new Response(
58 `Could not resolve domain "${subdomain.join(".")}.${ROOT_DOMAIN}"`,
59 {
60 status: 404,
61 }
62 );
63});