Add WebFinger endpoints

This commit is contained in:
Jesse Wierzbinski 2024-04-09 17:45:19 -10:00
parent ee6b6bce34
commit ae9698c647
No known key found for this signature in database
7 changed files with 34 additions and 17 deletions

View file

@ -87,6 +87,9 @@ export const rawRoutes = {
"/users/[uuid]": "./server/api/users/[uuid]/index", "/users/[uuid]": "./server/api/users/[uuid]/index",
"/users/[uuid]/inbox": "./server/api/users/[uuid]/inbox/index", "/users/[uuid]/inbox": "./server/api/users/[uuid]/inbox/index",
"/users/[uuid]/outbox": "./server/api/users/[uuid]/outbox/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]", "/[...404]": "./server/api/[...404]",
} as Record<string, string>; } as Record<string, string>;

View file

@ -101,8 +101,9 @@ export const createServer = (
return jsonResponse({}); 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( const { file: filePromise, matchedRoute } = await matchRoute(
req.url, req.url.replace(".well-known", "well-known"),
); );
const file = filePromise; const file = filePromise;

View file

@ -16,13 +16,10 @@ export const meta = applyConfig({
export default apiRoute(async (req, matchedRoute, extraData) => { export default apiRoute(async (req, matchedRoute, extraData) => {
const config = await extraData.configManager.getConfig(); const config = await extraData.configManager.getConfig();
return xmlResponse(` return xmlResponse(
<?xml version="1.0" encoding="UTF-8"?> `<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><Link rel="lrdd" template="${new URL(
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"> "/.well-known/webfinger",
<Link rel="lrdd" template="${new URL( config.http.base_url,
"/.well-known/webfinger", ).toString()}?resource={uri}"/></XRD>`,
config.http.base_url, );
).toString()}?resource={uri}"/>
</XRD>
`);
}); });

View file

@ -14,13 +14,29 @@ export const meta = applyConfig({
route: "/.well-known/webfinger", route: "/.well-known/webfinger",
}); });
export default apiRoute(async (req, matchedRoute, extraData) => { export default apiRoute<{
// In the format acct:name@example.com resource: string;
const resource = matchedRoute.query.resource; }>(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 requestedUser = resource.split("acct:")[1];
const config = await extraData.configManager.getConfig(); 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 // Check if user is a local user
if (requestedUser.split("@")[1] !== host) { if (requestedUser.split("@")[1] !== host) {
@ -28,7 +44,7 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
} }
const user = await client.user.findUnique({ const user = await client.user.findUnique({
where: { username: requestedUser.split("@")[0] }, where: { id: requestedUser.split("@")[0] },
}); });
if (!user) { if (!user) {
@ -36,7 +52,7 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
} }
return jsonResponse({ return jsonResponse({
subject: `acct:${user.username}@${host}`, subject: `acct:${user.id}@${host}`,
links: [ links: [
{ {

View file

@ -37,6 +37,6 @@
"**/*.ts", "**/*.ts",
"**/*.d.ts", "**/*.d.ts",
"**/*.vue", "**/*.vue",
"server/api/.well-known/**/*.ts" "server/api/well-known/**/*.ts"
] ]
} }