From fa3ed293f472a7ecb8bef5cb7cfb946b1e0abb5d Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Tue, 12 Sep 2023 10:53:30 -1000 Subject: [PATCH] Implement actor endpoint --- bun.lockb | Bin 79257 -> 79617 bytes package.json | 1 + server/api/@[username]/actor/index.ts | 36 ++++++++++++++++++++++++++ server/api/@[username]/inbox/index.ts | 24 +++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 server/api/@[username]/actor/index.ts create mode 100644 server/api/@[username]/inbox/index.ts diff --git a/bun.lockb b/bun.lockb index d4ae0e9b89d7e76175f2657bd6779de0db1ad06e..bd57f75f948bb05f69aabbb2543e7e9b9ac3d10d 100755 GIT binary patch delta 12629 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 delta 12169 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 P{xL*fMkU&KC`|u1N;y*G diff --git a/package.json b/package.json index 459dcd8d..5056ff83 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "module": "index.ts", "type": "module", "devDependencies": { + "@types/jsonld": "^1.5.9", "@typescript-eslint/eslint-plugin": "^6.6.0", "@typescript-eslint/parser": "^6.6.0", "activitypub-types": "^1.0.3", diff --git a/server/api/@[username]/actor/index.ts b/server/api/@[username]/actor/index.ts new file mode 100644 index 00000000..35a73426 --- /dev/null +++ b/server/api/@[username]/actor/index.ts @@ -0,0 +1,36 @@ +import { errorResponse, jsonResponse } from "@response"; +import { MatchedRoute } from "bun"; +import { User } from "~database/entities/User"; +import { getHost } from "@config"; +import { compact } from "jsonld"; + +/** + * ActivityPub user actor endpoinmt + */ +export default async ( + req: Request, + matchedRoute: MatchedRoute +): Promise => { + // In the format acct:name@example.com + const username = matchedRoute.params.username; + + const user = await User.findOneBy({ username }); + + if (!user) { + return errorResponse("User not found", 404); + } + + return jsonResponse( + await compact({ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + ], + id: `${getHost()}/@${user.username}/actor`, + type: "Person", + preferredUsername: user.username, + summary: user.bio, + inbox: `${getHost()}/@${user.username}/inbox`, + }) + ); +}; diff --git a/server/api/@[username]/inbox/index.ts b/server/api/@[username]/inbox/index.ts new file mode 100644 index 00000000..4ef7fca9 --- /dev/null +++ b/server/api/@[username]/inbox/index.ts @@ -0,0 +1,24 @@ +import { errorResponse, jsonResponse } from "@response"; +import { MatchedRoute } from "bun"; +import { User } from "~database/entities/User"; +import { getHost } from "@config"; +import { compact } from "jsonld"; + +/** + * ActivityPub user actor endpoinmt + */ +export default async ( + req: Request, + matchedRoute: MatchedRoute +): Promise => { + // In the format acct:name@example.com + const username = matchedRoute.params.username; + + const user = await User.findOneBy({ username }); + + if (!user) { + return errorResponse("User not found", 404); + } + + +};