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
*/
import { APIRoute } from "astro";
import type { APIRoute } from "astro";
import { normalizeURL } from "../../../util";
const PROJECTS = {
mastodon: {
checkUrl: "/api/v1/instance/rules",
publishEndpoint: "share",
params: {
text: "text",
interface FediverseProjectBasic {
publishEndpoint: string;
params: {
text: string;
};
}
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",
publishEndpoint: "/notice/new",
params: {
text: "status_textarea",
],
[
"gnuSocial",
{
checkUrl: "/api/gnusocial/config.xml",
publishEndpoint: "/notice/new",
params: {
text: "status_textarea",
},
},
},
pleroma: {
checkUrl: "/api/v1/pleroma/federation_status",
publishEndpoint: "share",
params: {
text: "message",
],
[
"pleroma",
{
checkUrl: "/api/v1/pleroma/federation_status",
publishEndpoint: "share",
params: {
text: "message",
},
},
},
friendica: {
checkUrl: "/api/statusnet/config",
publishEndpoint: "compose",
params: {
text: "body",
],
[
"friendica",
{
checkUrl: "/api/statusnet/config",
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 = (
urlToCheck: URL,
@ -57,19 +111,30 @@ const checkProjectUrl = (
};
export const get: APIRoute = async ({ params }) => {
const host = params.host;
const host = params.host as string;
const promises = Object.entries(PROJECTS).map(([service, { checkUrl }]) =>
checkProjectUrl(new URL(checkUrl, normalizeURL(host)), service),
);
const promises = Object.entries(PROJECTS).map(([service, project]) => {
const url = normalizeURL(host);
if (project.check !== undefined) {
return project.check(url);
}
return checkProjectUrl(new URL(project.checkUrl, url), service);
});
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(
JSON.stringify({
host,
project,
publishEndpoint: PROJECTS[project].publishEndpoint,
params: PROJECTS[project].params,
project: projectId,
publishEndpoint: project.publishEndpoint,
params: project.params,
}),
{
status: 200,