bun-activitypub/src/index.ts

81 lines
2.4 KiB
TypeScript
Raw Normal View History

import { DEFAULT_DOCUMENTS, HOSTNAME, STATIC_PATH } from "./env"
import admin from './admin'
import activitypub from "./activitypub"
import { fetchObject } from "./request"
import path from "path"
import { BunFile } from "bun"
import { rebuild } from "./db"
import ACTOR from "../actor"
rebuild()
const server = Bun.serve({
port: 3000,
fetch(req: Request): Response | Promise<Response> {
const url = new URL(req.url)
console.log(`${new Date().toISOString()} ${req.method} ${req.url}`)
if(req.method === "GET" && url.pathname === "/.well-known/webfinger") {
return webfinger(req, url.searchParams.get("resource"))
}
else if(req.method === "GET" && url.pathname === "/fetch") {
const object_url = url.searchParams.get('url')
if(!object_url) return new Response("No url supplied", { status: 400})
return fetchObject(object_url)
}
return admin(req) || activitypub(req) || staticFile(req)
},
});
const webfinger = async (req: Request, resource: string | null) => {
if(resource !== `acct:${ACTOR.preferredUsername}@${HOSTNAME}`) return new Response("", { status: 404 })
return Response.json({
subject: `acct:${ACTOR.preferredUsername}@${HOSTNAME}`,
aliases: [ACTOR.id],
links: [
{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": ACTOR.url
},
{
rel: "self",
type: "application/activity+json",
href: ACTOR.id,
},
],
}, { headers: { "content-type": "application/activity+json" }})
}
const getDefaultDocument = async(base_path: string) => {
for(const d of DEFAULT_DOCUMENTS){
const filePath = path.join(base_path, d)
const file = Bun.file(filePath)
if(await file.exists()) return file
}
}
const staticFile = async (req:Request): Promise<Response> => {
try{
const url = new URL(req.url)
const filePath = path.join(STATIC_PATH, url.pathname)
let file:BunFile|undefined = Bun.file(filePath)
// if the file doesn't exist, attempt to get the default document for the path
if(!(await file.exists())) file = await getDefaultDocument(filePath)
if(file && await file.exists()) return new Response(file)
// if the file still doesn't exist, just return a 404
else return new Response("", { status: 404 })
}
catch(err) {
console.error(err)
return new Response("", { status: 404 })
}
}
console.log(`Listening on http://localhost:${server.port} ...`);