From ae9698c6474a68b92b7d8ca0933be90db0c9d8f1 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Tue, 9 Apr 2024 17:45:19 -1000 Subject: [PATCH] Add WebFinger endpoints --- routes.ts | 3 ++ server.ts | 3 +- .../host-meta/index.ts | 15 ++++------ .../api/{.well-known => well-known}/lysand.ts | 0 .../nodeinfo/index.ts | 0 .../webfinger/index.ts | 28 +++++++++++++++---- tsconfig.json | 2 +- 7 files changed, 34 insertions(+), 17 deletions(-) rename server/api/{.well-known => well-known}/host-meta/index.ts (59%) rename server/api/{.well-known => well-known}/lysand.ts (100%) rename server/api/{.well-known => well-known}/nodeinfo/index.ts (100%) rename server/api/{.well-known => well-known}/webfinger/index.ts (60%) diff --git a/routes.ts b/routes.ts index 67d4a75c..2bb0026d 100644 --- a/routes.ts +++ b/routes.ts @@ -87,6 +87,9 @@ export const rawRoutes = { "/users/[uuid]": "./server/api/users/[uuid]/index", "/users/[uuid]/inbox": "./server/api/users/[uuid]/inbox/index", "/users/[uuid]/outbox": "./server/api/users/[uuid]/outbox/index", + // .well-known queries are automatically re-routed to well-known + "/well-known/webfinger": "./server/api/well-known/webfinger/index", + "/well-known/host-meta": "./server/api/well-known/host-meta/index", "/[...404]": "./server/api/[...404]", } as Record; diff --git a/server.ts b/server.ts index 6703851a..e45eb7f0 100644 --- a/server.ts +++ b/server.ts @@ -101,8 +101,9 @@ export const createServer = ( return jsonResponse({}); } + // If route is .well-known, remove dot because the filesystem router can't handle dots for some reason const { file: filePromise, matchedRoute } = await matchRoute( - req.url, + req.url.replace(".well-known", "well-known"), ); const file = filePromise; diff --git a/server/api/.well-known/host-meta/index.ts b/server/api/well-known/host-meta/index.ts similarity index 59% rename from server/api/.well-known/host-meta/index.ts rename to server/api/well-known/host-meta/index.ts index 723a99bd..1b2c85e5 100644 --- a/server/api/.well-known/host-meta/index.ts +++ b/server/api/well-known/host-meta/index.ts @@ -16,13 +16,10 @@ export const meta = applyConfig({ export default apiRoute(async (req, matchedRoute, extraData) => { const config = await extraData.configManager.getConfig(); - return xmlResponse(` - - - - - `); + return xmlResponse( + ``, + ); }); diff --git a/server/api/.well-known/lysand.ts b/server/api/well-known/lysand.ts similarity index 100% rename from server/api/.well-known/lysand.ts rename to server/api/well-known/lysand.ts diff --git a/server/api/.well-known/nodeinfo/index.ts b/server/api/well-known/nodeinfo/index.ts similarity index 100% rename from server/api/.well-known/nodeinfo/index.ts rename to server/api/well-known/nodeinfo/index.ts diff --git a/server/api/.well-known/webfinger/index.ts b/server/api/well-known/webfinger/index.ts similarity index 60% rename from server/api/.well-known/webfinger/index.ts rename to server/api/well-known/webfinger/index.ts index 1fdd5c59..682eaaa1 100644 --- a/server/api/.well-known/webfinger/index.ts +++ b/server/api/well-known/webfinger/index.ts @@ -14,13 +14,29 @@ export const meta = applyConfig({ route: "/.well-known/webfinger", }); -export default apiRoute(async (req, matchedRoute, extraData) => { - // In the format acct:name@example.com - const resource = matchedRoute.query.resource; +export default apiRoute<{ + resource: string; +}>(async (req, matchedRoute, extraData) => { + const { resource } = extraData.parsedRequest; + + if (!resource) return errorResponse("No resource provided", 400); + + // Check if resource is in the correct format (acct:uuid@domain) + if ( + !resource.match( + /^acct:[0-9A-F]{8}-[0-9A-F]{4}-[7][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}@.+/i, + ) + ) { + return errorResponse( + "Invalid resource (should be acct:uuid@domain)", + 400, + ); + } + const requestedUser = resource.split("acct:")[1]; const config = await extraData.configManager.getConfig(); - const host = new URL(config.http.base_url).hostname; + const host = new URL(config.http.base_url).host; // Check if user is a local user if (requestedUser.split("@")[1] !== host) { @@ -28,7 +44,7 @@ export default apiRoute(async (req, matchedRoute, extraData) => { } const user = await client.user.findUnique({ - where: { username: requestedUser.split("@")[0] }, + where: { id: requestedUser.split("@")[0] }, }); if (!user) { @@ -36,7 +52,7 @@ export default apiRoute(async (req, matchedRoute, extraData) => { } return jsonResponse({ - subject: `acct:${user.username}@${host}`, + subject: `acct:${user.id}@${host}`, links: [ { diff --git a/tsconfig.json b/tsconfig.json index 5cbff0d9..afbfd0bc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -37,6 +37,6 @@ "**/*.ts", "**/*.d.ts", "**/*.vue", - "server/api/.well-known/**/*.ts" + "server/api/well-known/**/*.ts" ] }