diff --git a/src/activitypub.ts b/src/activitypub.ts index 11cce94..fdf6135 100644 --- a/src/activitypub.ts +++ b/src/activitypub.ts @@ -11,7 +11,7 @@ import { listPosts, updateFollowing, } from "./db.js"; -import { HOSTNAME, ACCOUNT, PUBLIC_KEY } from "./env.js"; +import { HOSTNAME, PORT, ACCOUNT, PUBLIC_KEY } from "./env.js"; import { send, verify } from "./request.js"; export const activitypub = Router(); @@ -63,7 +63,7 @@ activitypub.post("/:actor/inbox", async (req, res) => { case "Follow": { await send(actor, body.actor, { "@context": "https://www.w3.org/ns/activitystreams", - id: `https://${HOSTNAME}/${crypto.randomUUID()}`, + id: `http://${HOSTNAME}:${PORT}/${crypto.randomUUID()}`, type: "Accept", actor, object: body, diff --git a/src/admin.ts b/src/admin.ts index 024ddcd..b60a7bf 100644 --- a/src/admin.ts +++ b/src/admin.ts @@ -4,7 +4,7 @@ import { is, omit, type } from "superstruct"; import { Router } from "express"; import basicAuth from "express-basic-auth"; -import { ADMIN_PASSWORD, ADMIN_USERNAME, HOSTNAME } from "./env.js"; +import { ADMIN_PASSWORD, ADMIN_USERNAME, HOSTNAME, PORT } from "./env.js"; import { createFollowing, createPost, @@ -61,16 +61,21 @@ admin.post("/create", async (req, res) => { return res.sendStatus(204); }); -admin.post("/follow/:actor", async (req, res) => { - const actor: string = req.app.get("actor"); - const object = req.params.actor; - const uri = `https://${HOSTNAME}/@${crypto.randomUUID()}`; - await send(actor, object, { +admin.post("/follow/:actor/:hostname/:port/:proto", async (req, res) => { + const our_actor: string = req.app.get("actor"); + console.log(`Follow endpoint, our actor: ${our_actor}`) + + const { proto, hostname, port, actor } = req.params; + const object = `${proto}://${hostname}:${port}/${actor}`; + console.log(`Follow endpoint, object: ${object}`) + const uri = `http://${HOSTNAME}:${PORT}/@${crypto.randomUUID()}`; + console.log(`Follow endpoint, uri: ${uri}`) + await send(our_actor, object, { "@context": "https://www.w3.org/ns/activitystreams", id: uri, type: "Follow", - actor, + actor: our_actor, object, }); diff --git a/src/index.ts b/src/index.ts index 676cc41..ffdabfe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,7 @@ import { admin } from "./admin.js"; const app = express(); -app.set("actor", `https://${HOSTNAME}/${ACCOUNT}`); +app.set("actor", `http://${HOSTNAME}:${PORT}/${ACCOUNT}`); app.use( express.text({ type: ["application/json", "application/activity+json"] }) diff --git a/src/request.ts b/src/request.ts index 462bcbd..71e14ff 100644 --- a/src/request.ts +++ b/src/request.ts @@ -7,6 +7,7 @@ import { assert } from "superstruct"; import { PRIVATE_KEY } from "./env.js"; import { Actor } from "./types.js"; + /** Fetches and returns an actor at a URL. */ async function fetchActor(url: string) { const res = await fetch(url, { @@ -31,7 +32,7 @@ export async function send(sender: string, recipient: string, message: object) { const url = new URL(recipient); const actor = await fetchActor(recipient); - const fragment = actor.inbox.replace("https://" + url.hostname, ""); + const fragment = url.pathname + "/inbox"; const body = JSON.stringify(message); const digest = crypto.createHash("sha256").update(body).digest("base64"); const d = new Date(); @@ -46,6 +47,7 @@ export async function send(sender: string, recipient: string, message: object) { const signature = crypto .sign("sha256", Buffer.from(data), key) .toString("base64"); + console.log(`crypto.sign("sha256", data: ${data}, key: ${key}, signature: ${signature})`); const res = await fetch(actor.inbox, { method: "POST", @@ -119,6 +121,7 @@ export async function verify(req: Request): Promise { return `${header}: ${req.get(header)}`; }) .join("\n"); + console.log(`crypto.verify("sha256", data: ${comparison}, key: ${key}, signature: ${included.signature})`); const data = Buffer.from(comparison); // verify the signature against the headers using the actor's public key