add /blogs/:username activitypub route
This commit is contained in:
parent
0fc002b399
commit
37d414314e
3 changed files with 60 additions and 7 deletions
20
src/ap/blog.ts
Normal file
20
src/ap/blog.ts
Normal 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
31
src/routes/ap/blog.ts
Normal 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;
|
|
@ -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([
|
||||||
host: IsNull(),
|
MercuryDataSource.getRepository(Blog).countBy({
|
||||||
});
|
host: IsNull(),
|
||||||
const postCount = await MercuryDataSource.getRepository(Post).count({
|
}),
|
||||||
relations: { blog: true },
|
MercuryDataSource.getRepository(Post).count({
|
||||||
where: { blog: { host: IsNull() } },
|
relations: { blog: true },
|
||||||
});
|
where: { blog: { host: IsNull() } },
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
res.send({
|
res.send({
|
||||||
version: "2.0",
|
version: "2.0",
|
||||||
|
|
Loading…
Reference in a new issue