2023-09-27 04:13:10 +00:00
|
|
|
import { ACCOUNT, ACTOR, DEFAULT_DOCUMENTS, HOSTNAME, PORT, STATIC_PATH } from "./env";
|
2023-09-16 00:28:06 +00:00
|
|
|
import admin from './admin'
|
|
|
|
|
import activitypub from "./activitypub";
|
2023-09-20 06:43:48 +00:00
|
|
|
import { fetchObject } from "./request";
|
2023-09-27 04:13:10 +00:00
|
|
|
import path from "path"
|
|
|
|
|
import { BunFile } from "bun";
|
|
|
|
|
const { stat } = require("fs").promises
|
2023-09-16 00:28:06 +00:00
|
|
|
|
|
|
|
|
const server = Bun.serve({
|
|
|
|
|
port: 3000,
|
2023-09-26 23:49:32 +00:00
|
|
|
fetch(req: Request): Response | Promise<Response> {
|
2023-09-16 00:28:06 +00:00
|
|
|
const url = new URL(req.url)
|
|
|
|
|
|
|
|
|
|
console.log(`${new Date().toISOString()} ${req.method} ${req.url}`)
|
|
|
|
|
|
|
|
|
|
if(req.method === "GET" && url.pathname === "/.well-known/webfinger") {
|
2023-09-26 23:49:32 +00:00
|
|
|
return webfinger(req, url.searchParams.get("resource"))
|
2023-09-16 00:28:06 +00:00
|
|
|
}
|
2023-09-20 06:43:48 +00:00
|
|
|
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(ACTOR, object_url)
|
|
|
|
|
}
|
2023-09-16 00:28:06 +00:00
|
|
|
|
2023-09-27 04:13:10 +00:00
|
|
|
return admin(req) || activitypub(req) || staticFile(req)
|
2023-09-16 00:28:06 +00:00
|
|
|
},
|
|
|
|
|
});
|
2023-09-26 23:49:32 +00:00
|
|
|
|
|
|
|
|
const webfinger = async (req: Request, resource: string | null) => {
|
|
|
|
|
|
|
|
|
|
if(resource !== `acct:${ACCOUNT}@${HOSTNAME}`) return new Response("", { status: 404 })
|
|
|
|
|
|
|
|
|
|
return Response.json({
|
|
|
|
|
subject: `acct:${ACCOUNT}@${HOSTNAME}`,
|
|
|
|
|
aliases: [ACTOR],
|
|
|
|
|
links: [
|
|
|
|
|
{
|
|
|
|
|
"rel": "http://webfinger.net/rel/profile-page",
|
|
|
|
|
"type": "text/html",
|
|
|
|
|
"href": ACTOR
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
rel: "self",
|
|
|
|
|
type: "application/activity+json",
|
|
|
|
|
href: ACTOR,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
}, { headers: { "content-type": "application/activity+json" }})
|
|
|
|
|
}
|
2023-09-27 04:13:10 +00:00
|
|
|
|
|
|
|
|
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 })
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-16 00:28:06 +00:00
|
|
|
|
|
|
|
|
console.log(`Listening on http://localhost:${server.port} ...`);
|