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([
 | 
				
			||||||
 | 
					      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",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue