add /blogs/:username activitypub route

This commit is contained in:
sam 2023-07-21 03:35:12 +02:00
parent 0fc002b399
commit 37d414314e
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
3 changed files with 60 additions and 7 deletions

20
src/ap/blog.ts Normal file
View file

@ -0,0 +1,20 @@
import { BASE_URL } from "~/config.js";
import { Blog } from "~/db/entities/blog.js";
/** Transforms the given Blog into an ActivityPub Person. It is the caller's responsibility to ensure the blog is local. */
export function blogToActivityPub(blog: Blog) {
return {
"@context": "https://www.w3.org/ns/activitystreams",
type: "Person",
id: `${BASE_URL}/blogs/${blog.username}`,
inbox: `${BASE_URL}/blogs/${blog.username}/inbox`,
outbox: `${BASE_URL}/blogs/${blog.username}/outbox`,
name: blog.username,
preferredUsername: blog.username,
publicKey: {
id: `${BASE_URL}/blogs/${blog.username}#main-key`,
owner: `${BASE_URL}/blogs/${blog.username}`,
publicKeyPem: blog.publicKey,
},
};
}

31
src/routes/ap/blog.ts Normal file
View file

@ -0,0 +1,31 @@
import { RouteOptions } from "fastify";
import MercuryDataSource from "~/db/index.js";
import { Blog } from "~/db/entities/blog.js";
import { IsNull } from "typeorm";
import { blogToActivityPub } from "~/ap/blog.js";
const route: RouteOptions = {
method: "GET",
url: "/blogs/:username",
handler: async (req, res) => {
const username = (req.params as { username: string }).username;
// Only respond to ActivityPub requests
if (req.headers.accept && !req.headers.accept.indexOf("application/json")) {
res.redirect(303, `/@${username}`);
}
const blog = await MercuryDataSource.getRepository(Blog).findOneBy({
username,
host: IsNull(),
});
if (!blog) {
return res.status(404).send({ message: "Not found" });
}
return res.send(blogToActivityPub(blog));
},
};
export default route;

View file

@ -9,13 +9,15 @@ const route: RouteOptions = {
method: "GET", method: "GET",
url: "/nodeinfo/2.0", url: "/nodeinfo/2.0",
handler: async (_, res) => { handler: async (_, res) => {
const userCount = await MercuryDataSource.getRepository(Blog).countBy({ const [userCount, postCount] = await Promise.all([
MercuryDataSource.getRepository(Blog).countBy({
host: IsNull(), host: IsNull(),
}); }),
const postCount = await MercuryDataSource.getRepository(Post).count({ MercuryDataSource.getRepository(Post).count({
relations: { blog: true }, relations: { blog: true },
where: { blog: { host: IsNull() } }, where: { blog: { host: IsNull() } },
}); }),
]);
res.send({ res.send({
version: "2.0", version: "2.0",