feat(federation): Add WebFinger forwarding to bridge for ActivityPub requests

This commit is contained in:
Jesse Wierzbinski 2024-07-17 14:46:43 +02:00
parent be881f18cd
commit fea19eeb2e
No known key found for this signature in database
3 changed files with 42 additions and 2 deletions

BIN
bun.lockb

Binary file not shown.

View file

@ -104,7 +104,7 @@
"@json2csv/plainjs": "^7.0.6", "@json2csv/plainjs": "^7.0.6",
"@logtape/logtape": "npm:@jsr/logtape__logtape@0.4.2", "@logtape/logtape": "npm:@jsr/logtape__logtape@0.4.2",
"@lysand-org/client": "^0.2.4", "@lysand-org/client": "^0.2.4",
"@lysand-org/federation": "^2.1.1", "@lysand-org/federation": "^2.1.2",
"@oclif/core": "^4.0.12", "@oclif/core": "^4.0.12",
"@tufjs/canonical-json": "^2.0.0", "@tufjs/canonical-json": "^2.0.0",
"altcha-lib": "^0.4.0", "altcha-lib": "^0.4.0",

View file

@ -7,6 +7,12 @@ import {
import { errorResponse, jsonResponse } from "@/response"; import { errorResponse, jsonResponse } from "@/response";
import type { Hono } from "@hono/hono"; import type { Hono } from "@hono/hono";
import { zValidator } from "@hono/zod-validator"; import { zValidator } from "@hono/zod-validator";
import { getLogger } from "@logtape/logtape";
import { SignatureConstructor } from "@lysand-org/federation";
import {
FederationRequester,
type ResponseError,
} from "@lysand-org/federation/requester";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { lookup } from "mime-types"; import { lookup } from "mime-types";
import { z } from "zod"; import { z } from "zod";
@ -70,6 +76,35 @@ export default (app: Hono) =>
return errorResponse("User not found", 404); return errorResponse("User not found", 404);
} }
let activityPubUrl = "";
if (config.federation.bridge.enabled) {
const requester = await User.getServerActor();
const signatureConstructor =
await SignatureConstructor.fromStringKey(
requester.data.privateKey ?? "",
requester.getUri(),
);
const manager = new FederationRequester(
new URL(config.federation.bridge.url ?? ""),
signatureConstructor,
);
try {
activityPubUrl = await manager.webFinger(
user.data.username,
new URL(config.http.base_url).host,
);
} catch (e) {
const error = e as ResponseError;
getLogger("federation")
.error`Error from bridge: ${await error.response.data}`;
}
}
return jsonResponse({ return jsonResponse({
subject: `acct:${ subject: `acct:${
isUuid ? user.id : user.data.username isUuid ? user.id : user.data.username
@ -84,12 +119,17 @@ export default (app: Hono) =>
config.http.base_url, config.http.base_url,
).toString(), ).toString(),
}, },
activityPubUrl && {
rel: "self",
type: "application/activity+json",
href: activityPubUrl,
},
{ {
rel: "avatar", rel: "avatar",
type: lookup(user.getAvatarUrl(config)), type: lookup(user.getAvatarUrl(config)),
href: user.getAvatarUrl(config), href: user.getAvatarUrl(config),
}, },
], ].filter(Boolean),
}); });
}, },
); );