+2
-1
.gitignore
+2
-1
.gitignore
server/blobs/did:web:invalid/cat
server/blobs/did:web:invalid/cat
This is a binary file and will not be displayed.
-11
server/blobs/did:web:invalid/hello
-11
server/blobs/did:web:invalid/hello
-19
server/blobs/did:web:invalid/root
-19
server/blobs/did:web:invalid/root
···
1
-
<!DOCTYPE html>
2
-
<html lang="en">
3
-
<head>
4
-
<meta charset="UTF-8" />
5
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
-
<title>did:web:invalid from cdn</title>
7
-
</head>
8
-
<body>
9
-
this site is served from the cdn.<br />
10
-
all pages:
11
-
<ul>
12
-
<li><a href="404-page-here">404</a></li>
13
-
<li><a href="/">::</a></li>
14
-
<li><a href="/hello.html">::hello.html</a></li>
15
-
<li><a href="/cat.png">::cat.png</a></li>
16
-
<li><a href="/styles.css">::styles.css</a></li>
17
-
</ul>
18
-
</body>
19
-
</html>
-11
server/blobs/did:web:invalid/this_is_a_cid
-11
server/blobs/did:web:invalid/this_is_a_cid
+39
server/src/backfill/blob.ts
+39
server/src/backfill/blob.ts
···
1
+
import { Client, simpleFetchHandler } from "@atcute/client";
2
+
import { getPds } from "../utils.ts";
3
+
4
+
export default async function (
5
+
did: `did:${"plc" | "web"}:${string}`,
6
+
cid: string
7
+
): Promise<Blob> {
8
+
const pds = await getPds(did);
9
+
if (!pds) throw "PDS not found";
10
+
11
+
const { data, ok } = await new Client({
12
+
handler: simpleFetchHandler({ service: pds }),
13
+
}).get("com.atproto.sync.getBlob", {
14
+
params: {
15
+
did,
16
+
cid,
17
+
},
18
+
as: "blob",
19
+
});
20
+
21
+
if (!ok) throw `${data.error}`;
22
+
23
+
// check for CSAM etc here
24
+
25
+
await Deno.mkdir(`./blobs/${did}`, { recursive: true })
26
+
.then(async () =>
27
+
Deno.writeFile(`./blobs/${did}/${cid}`, await data.bytes(), {
28
+
createNew: true,
29
+
})
30
+
)
31
+
.catch((err) => {
32
+
if (err instanceof Error) {
33
+
err.cause = "Deno.writefile";
34
+
}
35
+
throw err;
36
+
});
37
+
38
+
return data;
39
+
}
+19
-8
server/src/routes/user.ts
+19
-8
server/src/routes/user.ts
···
6
6
} from "@atcute/identity-resolver";
7
7
import { and, eq } from "drizzle-orm";
8
8
import { routes } from "../db/schema.ts";
9
-
import { type db, ROOT_DOMAIN } from "../utils.ts";
9
+
import { type db, isDid, ROOT_DOMAIN } from "../utils.ts";
10
10
import ascii from "./ascii.txt" with { type: "text" };
11
+
import storeBlob from "../backfill/blob.ts";
11
12
12
13
const handleResolver = new CompositeHandleResolver({
13
14
strategy: "race",
···
89
90
},
90
91
});
91
92
} catch {
92
-
return new Response(`${ascii}
93
+
if (!isDid(db_res.did))
94
+
return new Response(`${ascii}
93
95
94
-
This page isn't stored in the CDN.
95
-
TODO:
96
-
Fetch the content from the pds,
97
-
check its hash,
98
-
serve it if not known as illegal,
99
-
store in cdn if doesnt take account over fs limit
96
+
${db_res.did} is not a valid DID. This account could not be resolved
100
97
`);
98
+
try {
99
+
const blob = await storeBlob(db_res.did, db_res.blob_cid);
100
+
return new Response(blob, {
101
+
headers: {
102
+
"Content-Type": db_res.mime,
103
+
},
104
+
});
105
+
} catch (e) {
106
+
console.error(e);
107
+
return new Response(`${ascii}
108
+
109
+
This page couldn't be resolved. Either the blob does not exist, or contained illegal content.
110
+
`);
111
+
}
101
112
}
102
113
}