tmcw-activitypub.web.val.run
Readme

WebFinger

This is a not-quite-complete ActivityPub implementation based on my blog post about building an AP implementation. It includes enough to look up bot@tmcw-activitypub.web.val.run on Mastodon and get some basic information.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
export const activitypub = async (req: Request) => {
const { Hono } = await import("npm:hono@3.4.3");
const app = new Hono();
const DOMAIN = "tmcw-activitypub.web.val.run";
const USERS = new Map([
[
`acct:bot@${DOMAIN}`,
{
subject: `acct:bot@${DOMAIN}`,
aliases: [],
links: [
{
rel: "http://webfinger.net/rel/profile-page",
type: "text/html",
href: `https://${DOMAIN}/profile`,
},
{
rel: "self",
type: "application/activity+json",
href: `https://${DOMAIN}/u/bot`,
},
],
},
],
]);
const publicKey = `-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7LBs3Qyuh93lRboTNXLN
hj4n92oK5Qg4oS8Cc81AXh04hD7nQSSKBhtarbHy2yPXeiKA+H3EGbcflsLvZCo2
B3OPNo2nGTCMyJM8HWDf/7JCOHHcy4tZC1ldjrItkb1YDABWwfoXxyBiGTyTVXjL
sBX5ArTGUPwctMSOdxlJp0ttFn5WDIHiPzxbSaEX/fzTy+HKr9RvYPu/hWWpXA/W
8QQRacZjslweupZFGCGPX1zJ+P0FSe81uV6N5cOPpy+vFkBQrvApwCSIyp/n7Rfq
UtU+zi/ru+wSxyvnoZPZa+zOXst8+pk7lIbmI6dyJ2+wijkykAxKt2DnDXWOSUGM
R+aNjc6tt8xp2MwmhAz91f1rIt2+jOhkPZ0m6aLV3B86J3iI0BIHXzQNydDtz5/P
EOj79vnnDwjCrWmbsfsIVCmECQDS7EW6Lzdc98GyiD/vyA4Epg3QgpeN4r7fELZj
8IfJJ7J8Z8nYewRoCVNnfvXpR26y+CLftMUi9LtPP1N78er1IdvZEer/8RIAc58r
S5VmDYBBfEduxPh/l3tn4A5Ri8smue26yG+wPkBj3CSqaOaNFxxZPgXcbI2OePrH
81goKk17g+5O0sZJGv+EAeFM1OQPXKqyu0DLY6PHJKGSho/B/BNWQ34vZnQhQF1r
++VZAcLEeqny/Cn6CHoeu5cCAwEAAQ==
-----END PUBLIC KEY-----`;
app.get("/u/bot", (ctx) => {
return ctx.json({
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
],
id: `https://${DOMAIN}/u/bot`,
type: "Person",
preferredUsername: `bot`,
summary: `Photos from ${DOMAIN}.com`,
inbox: `https://${DOMAIN}/api/inbox`,
followers: `https://${DOMAIN}/u/bot/followers`,
icon: {
type: "Image",
mediaType: "image/jpeg",
url: "https://macwright.com/graphics/about.jpg",
},
publicKey: {
id: `https://${DOMAIN}/u/bot#main-key`,
owner: `https://${DOMAIN}/u/bot`,
publicKeyPem: publicKey,
},
});
});
app.get("/.well-known/webfinger", (ctx) => {
const u = new URL(ctx.req.url);
const resource = u.searchParams.get("resource");
if (resource && USERS.has(resource)) {
return new Response(JSON.stringify(USERS.get(resource)), {
status: 200,
headers: { "Content-Type": "application/jrd+json" },
});
}
return new Response("", {
status: 404,
headers: { "Content-Type": "text/html" },
});
});
return app.fetch(req);
};
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
October 23, 2023