Kinda implement Hubzilla?

This commit is contained in:
Nikita Karamov 2023-03-18 04:14:14 +01:00
parent e1aa6966c0
commit cb0fc3e11d
No known key found for this signature in database
GPG Key ID: 41D6F71EE78E77CD
1 changed files with 100 additions and 35 deletions

View File

@ -3,39 +3,93 @@
* Licensed under AGPL v3 or later * Licensed under AGPL v3 or later
*/ */
import { APIRoute } from "astro"; import type { APIRoute } from "astro";
import { normalizeURL } from "../../../util"; import { normalizeURL } from "../../../util";
const PROJECTS = { interface FediverseProjectBasic {
mastodon: { publishEndpoint: string;
checkUrl: "/api/v1/instance/rules", params: {
publishEndpoint: "share", text: string;
params: { };
text: "text", }
interface FediverseProjectCheckFunction extends FediverseProjectBasic {
check: (url: string) => Promise<string>;
}
interface FediverseProjectCheckUrl extends FediverseProjectBasic {
checkUrl: string;
}
type FediverseProject =
| FediverseProjectCheckUrl
| FediverseProjectCheckFunction;
const PROJECTS: Map<string, FediverseProject> = new Map([
[
"mastodon",
{
checkUrl: "/api/v1/instance/rules",
publishEndpoint: "share",
params: {
text: "text",
},
}, },
}, ],
gnuSocial: { [
checkUrl: "/api/gnusocial/config.xml", "gnuSocial",
publishEndpoint: "/notice/new", {
params: { checkUrl: "/api/gnusocial/config.xml",
text: "status_textarea", publishEndpoint: "/notice/new",
params: {
text: "status_textarea",
},
}, },
}, ],
pleroma: { [
checkUrl: "/api/v1/pleroma/federation_status", "pleroma",
publishEndpoint: "share", {
params: { checkUrl: "/api/v1/pleroma/federation_status",
text: "message", publishEndpoint: "share",
params: {
text: "message",
},
}, },
}, ],
friendica: { [
checkUrl: "/api/statusnet/config", "friendica",
publishEndpoint: "compose", {
params: { checkUrl: "/api/statusnet/config",
text: "body", publishEndpoint: "compose",
params: {
text: "body",
},
}, },
}, ],
}; [
"hubzilla",
{
check: async (url: string): Promise<string> => {
const response = await fetch(url);
const htmlBody = await response.text();
console.debug(htmlBody);
if (
htmlBody.includes(
'<meta name="application-name" content="hubzilla" />',
)
) {
return "hubzilla";
}
throw new Error(`${url} doesn't host Hubzilla`);
},
checkUrl: "/.well-known/zot-info",
publishEndpoint: "rpost",
params: {
text: "body",
},
},
],
]);
const checkProjectUrl = ( const checkProjectUrl = (
urlToCheck: URL, urlToCheck: URL,
@ -57,19 +111,30 @@ const checkProjectUrl = (
}; };
export const get: APIRoute = async ({ params }) => { export const get: APIRoute = async ({ params }) => {
const host = params.host; const host = params.host as string;
const promises = Object.entries(PROJECTS).map(([service, { checkUrl }]) => const promises = Object.entries(PROJECTS).map(([service, project]) => {
checkProjectUrl(new URL(checkUrl, normalizeURL(host)), service), const url = normalizeURL(host);
); if (project.check !== undefined) {
return project.check(url);
}
return checkProjectUrl(new URL(project.checkUrl, url), service);
});
try { try {
const project = await Promise.any(promises); const projectId = await Promise.any(promises);
if (!PROJECTS.has(projectId)) {
throw new Error(`Unexpected project ID: ${projectId}`);
}
const project = PROJECTS.get(projectId) as FediverseProject;
return new Response( return new Response(
JSON.stringify({ JSON.stringify({
host, host,
project, project: projectId,
publishEndpoint: PROJECTS[project].publishEndpoint, publishEndpoint: project.publishEndpoint,
params: PROJECTS[project].params, params: project.params,
}), }),
{ {
status: 200, status: 200,