From 7f2e89ab20048e750ced8d720ada406d1bf6d238 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Mon, 16 Oct 2023 07:39:41 -1000 Subject: [PATCH] Add more API route definitions --- server/api/.well-known/host-meta/index.ts | 19 ++++++++++++++++-- server/api/.well-known/nodeinfo/index.ts | 20 +++++++++++++++++-- server/api/.well-known/webfinger/index.ts | 13 ++++++++++++ server/api/nodeinfo/2.0/index.ts | 13 ++++++++++++ server/api/oauth/authorize/index.ts | 13 ++++++++++++ server/api/oauth/token/index.ts | 13 ++++++++++++ server/api/object/[uuid]/index.ts | 13 ++++++++++++ server/api/users/[username]/actor/index.ts | 15 +++++++++++++- server/api/users/[username]/inbox/index.ts | 18 ++++++++++++----- .../{outbox.json => outbox}/index.ts | 13 ++++++++++++ 10 files changed, 140 insertions(+), 10 deletions(-) rename server/api/users/[username]/{outbox.json => outbox}/index.ts (94%) diff --git a/server/api/.well-known/host-meta/index.ts b/server/api/.well-known/host-meta/index.ts index c6f9490e..2d746185 100644 --- a/server/api/.well-known/host-meta/index.ts +++ b/server/api/.well-known/host-meta/index.ts @@ -1,6 +1,20 @@ import { MatchedRoute } from "bun"; -import { getHost } from "@config"; +import { getConfig, getHost } from "@config"; import { xmlResponse } from "@response"; +import { applyConfig } from "@api"; + +export const meta = applyConfig({ + allowedMethods: ["GET"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 60, + }, + route: "/.well-known/host-meta", +}); + /** * Host meta endpoint @@ -9,10 +23,11 @@ export default async ( req: Request, matchedRoute: MatchedRoute ): Promise => { + const config = getConfig(); return xmlResponse(` - + `); }; diff --git a/server/api/.well-known/nodeinfo/index.ts b/server/api/.well-known/nodeinfo/index.ts index a4c49d41..b8ae2fea 100644 --- a/server/api/.well-known/nodeinfo/index.ts +++ b/server/api/.well-known/nodeinfo/index.ts @@ -1,5 +1,19 @@ import { MatchedRoute } from "bun"; -import { getHost } from "@config"; +import { getConfig, getHost } from "@config"; +import { applyConfig } from "@api"; + +export const meta = applyConfig({ + allowedMethods: ["GET"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 60, + }, + route: "/.well-known/nodeinfo", +}); + /** * Redirect to /nodeinfo/2.0 @@ -8,10 +22,12 @@ export default async ( req: Request, matchedRoute: MatchedRoute ): Promise => { + const config = getConfig(); + return new Response("", { status: 301, headers: { - Location: `https://${getHost()}/.well-known/nodeinfo/2.0`, + Location: `${config.http.base_url}/.well-known/nodeinfo/2.0`, }, }); }; diff --git a/server/api/.well-known/webfinger/index.ts b/server/api/.well-known/webfinger/index.ts index 9bf6c3a5..2b8fb4a1 100644 --- a/server/api/.well-known/webfinger/index.ts +++ b/server/api/.well-known/webfinger/index.ts @@ -2,6 +2,19 @@ import { errorResponse, jsonResponse } from "@response"; import { MatchedRoute } from "bun"; import { User } from "~database/entities/User"; import { getConfig, getHost } from "@config"; +import { applyConfig } from "@api"; + +export const meta = applyConfig({ + allowedMethods: ["GET"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 60, + }, + route: "/.well-known/webfinger", +}); /** * ActivityPub WebFinger endpoint diff --git a/server/api/nodeinfo/2.0/index.ts b/server/api/nodeinfo/2.0/index.ts index eb331439..8d3c0cef 100644 --- a/server/api/nodeinfo/2.0/index.ts +++ b/server/api/nodeinfo/2.0/index.ts @@ -1,5 +1,18 @@ +import { applyConfig } from "@api"; import { jsonResponse } from "@response"; +export const meta = applyConfig({ + allowedMethods: ["GET"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 500, + }, + route: "/nodeinfo/2.0", +}); + /** * ActivityPub nodeinfo 2.0 endpoint */ diff --git a/server/api/oauth/authorize/index.ts b/server/api/oauth/authorize/index.ts index 45a6d3f3..0cf4c74d 100644 --- a/server/api/oauth/authorize/index.ts +++ b/server/api/oauth/authorize/index.ts @@ -1,5 +1,18 @@ +import { applyConfig } from "@api"; import { MatchedRoute } from "bun"; +export const meta = applyConfig({ + allowedMethods: ["GET"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 20, + }, + route: "/oauth/authorize", +}); + /** * Returns an HTML login form */ diff --git a/server/api/oauth/token/index.ts b/server/api/oauth/token/index.ts index dc1284cf..7e3fa9f0 100644 --- a/server/api/oauth/token/index.ts +++ b/server/api/oauth/token/index.ts @@ -1,7 +1,20 @@ +import { applyConfig } from "@api"; import { parseRequest } from "@request"; import { errorResponse, jsonResponse } from "@response"; import { Token } from "~database/entities/Token"; +export const meta = applyConfig({ + allowedMethods: ["POST"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 10, + }, + route: "/oauth/token", +}); + /** * Allows getting token from OAuth code */ diff --git a/server/api/object/[uuid]/index.ts b/server/api/object/[uuid]/index.ts index 4b15c5de..c72239f6 100644 --- a/server/api/object/[uuid]/index.ts +++ b/server/api/object/[uuid]/index.ts @@ -1,7 +1,20 @@ +import { applyConfig } from "@api"; import { errorResponse, jsonLdResponse } from "@response"; import { MatchedRoute } from "bun"; import { RawActivity } from "~database/entities/RawActivity"; +export const meta = applyConfig({ + allowedMethods: ["GET"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 500, + }, + route: "/object/:id", +}); + /** * Fetch a user */ diff --git a/server/api/users/[username]/actor/index.ts b/server/api/users/[username]/actor/index.ts index 8199cdd7..f2991fbf 100644 --- a/server/api/users/[username]/actor/index.ts +++ b/server/api/users/[username]/actor/index.ts @@ -2,6 +2,19 @@ import { errorResponse, jsonLdResponse } from "@response"; import { MatchedRoute } from "bun"; import { User } from "~database/entities/User"; import { getConfig, getHost } from "@config"; +import { applyConfig } from "@api"; + +export const meta = applyConfig({ + allowedMethods: ["GET"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 500, + }, + route: "/users/:username/actor", +}); /** * ActivityPub user actor endpoinmt @@ -19,7 +32,7 @@ export default async ( const config = getConfig(); - const username = matchedRoute.params.username.replace("@", ""); + const username = matchedRoute.params.username; const user = await User.findOneBy({ username }); diff --git a/server/api/users/[username]/inbox/index.ts b/server/api/users/[username]/inbox/index.ts index 8aa3d3fa..0faa8517 100644 --- a/server/api/users/[username]/inbox/index.ts +++ b/server/api/users/[username]/inbox/index.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { applyConfig } from "@api"; import { getConfig } from "@config"; import { errorResponse, jsonResponse } from "@response"; import { @@ -19,6 +20,18 @@ import { RawActivity } from "~database/entities/RawActivity"; import { RawActor } from "~database/entities/RawActor"; import { User } from "~database/entities/User"; +export const meta = applyConfig({ + allowedMethods: ["POST"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 500, + }, + route: "/users/:username/inbox", +}); + /** * ActivityPub user inbox endpoint */ @@ -26,11 +39,6 @@ export default async ( req: Request, matchedRoute: MatchedRoute ): Promise => { - // Check if POST request - if (req.method !== "POST") { - return errorResponse("Method not allowed", 405); - } - const username = matchedRoute.params.username; const config = getConfig(); diff --git a/server/api/users/[username]/outbox.json/index.ts b/server/api/users/[username]/outbox/index.ts similarity index 94% rename from server/api/users/[username]/outbox.json/index.ts rename to server/api/users/[username]/outbox/index.ts index d192aa86..492a5364 100644 --- a/server/api/users/[username]/outbox.json/index.ts +++ b/server/api/users/[username]/outbox/index.ts @@ -4,6 +4,19 @@ import { User } from "~database/entities/User"; import { getHost } from "@config"; import { NodeObject, compact } from "jsonld"; import { RawActivity } from "~database/entities/RawActivity"; +import { applyConfig } from "@api"; + +export const meta = applyConfig({ + allowedMethods: ["GET"], + auth: { + required: false, + }, + ratelimits: { + duration: 60, + max: 500, + }, + route: "/users/:username/outbox", +}); /** * ActivityPub user outbox endpoint