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]/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<string, string>;

View file

@ -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;

View file

@ -16,13 +16,10 @@ export const meta = applyConfig({
export default apiRoute(async (req, matchedRoute, extraData) => {
const config = await extraData.configManager.getConfig();
return xmlResponse(`
<?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(
return xmlResponse(
`<?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(
"/.well-known/webfinger",
config.http.base_url,
).toString()}?resource={uri}"/>
</XRD>
`);
).toString()}?resource={uri}"/></XRD>`,
);
});

View file

@ -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: [
{

View file

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