diff options
| -rw-r--r-- | src/routes/activitypub.ts | 284 | 
1 files changed, 150 insertions, 134 deletions
diff --git a/src/routes/activitypub.ts b/src/routes/activitypub.ts index fc61dd7..5f141ec 100644 --- a/src/routes/activitypub.ts +++ b/src/routes/activitypub.ts @@ -21,71 +21,79 @@ const send404IfNotFederated = (      next();  }; -router.use(send404IfNotFederated); -  // return the JSON for the featured/pinned post for this event -router.get("/:eventID/featured", (req: Request, res: Response) => { -    const { eventID } = req.params; -    const featured = { -        "@context": "https://www.w3.org/ns/activitystreams", -        id: `https://${res.locals.config?.general.domain}/${eventID}/featured`, -        type: "OrderedCollection", -        orderedItems: [createFeaturedPost(eventID)], -    }; -    if (acceptsActivityPub(req)) { -        res.header("Content-Type", "application/activity+json").send(featured); -    } else { -        res.header("Content-Type", "application/json").send(featured); -    } -}); +router.get( +    "/:eventID/featured", +    send404IfNotFederated, +    (req: Request, res: Response) => { +        const { eventID } = req.params; +        const featured = { +            "@context": "https://www.w3.org/ns/activitystreams", +            id: `https://${res.locals.config?.general.domain}/${eventID}/featured`, +            type: "OrderedCollection", +            orderedItems: [createFeaturedPost(eventID)], +        }; +        if (acceptsActivityPub(req)) { +            res.header("Content-Type", "application/activity+json").send( +                featured, +            ); +        } else { +            res.header("Content-Type", "application/json").send(featured); +        } +    }, +);  // return the JSON for a given activitypub message -router.get("/:eventID/m/:hash", async (req: Request, res: Response) => { -    const { hash, eventID } = req.params; -    const id = `https://${res.locals.config?.general.domain}/${eventID}/m/${hash}`; +router.get( +    "/:eventID/m/:hash", +    send404IfNotFederated, +    async (req: Request, res: Response) => { +        const { hash, eventID } = req.params; +        const id = `https://${res.locals.config?.general.domain}/${eventID}/m/${hash}`; -    try { -        const event = await Event.findOne({ -            id: eventID, -        }); -        if (!event) { -            return res.status(404).render("404", frontendConfig(res)); -        } else { -            if (!event.activityPubMessages) { +        try { +            const event = await Event.findOne({ +                id: eventID, +            }); +            if (!event) {                  return res.status(404).render("404", frontendConfig(res)); -            } -            const message = event.activityPubMessages.find( -                (el) => el.id === id, -            ); -            if (message) { -                if (acceptsActivityPub(req)) { -                    res.header( -                        "Content-Type", -                        "application/activity+json", -                    ).send(JSON.parse(message.content || "{}")); +            } else { +                if (!event.activityPubMessages) { +                    return res.status(404).render("404", frontendConfig(res)); +                } +                const message = event.activityPubMessages.find( +                    (el) => el.id === id, +                ); +                if (message) { +                    if (acceptsActivityPub(req)) { +                        res.header( +                            "Content-Type", +                            "application/activity+json", +                        ).send(JSON.parse(message.content || "{}")); +                    } else { +                        res.header("Content-Type", "application/json").send( +                            JSON.parse(message.content || "{}"), +                        ); +                    }                  } else { -                    res.header("Content-Type", "application/json").send( -                        JSON.parse(message.content || "{}"), -                    ); +                    return res.status(404).render("404", frontendConfig(res));                  } -            } else { -                return res.status(404).render("404", frontendConfig(res));              } +        } catch (err) { +            addToLog( +                "getActivityPubMessage", +                "error", +                "Attempt to get Activity Pub Message for " + +                    id + +                    " failed with error: " + +                    err, +            ); +            return res.status(404).render("404", frontendConfig(res));          } -    } catch (err) { -        addToLog( -            "getActivityPubMessage", -            "error", -            "Attempt to get Activity Pub Message for " + -                id + -                " failed with error: " + -                err, -        ); -        return res.status(404).render("404", frontendConfig(res)); -    } -}); +    }, +); -router.get("/.well-known/nodeinfo", (req, res) => { +router.get("/.well-known/nodeinfo", send404IfNotFederated, (req, res) => {      if (!res.locals.config?.general.is_federated) {          return res.status(404).render("404", frontendConfig(res));      } @@ -103,94 +111,102 @@ router.get("/.well-known/nodeinfo", (req, res) => {      ).send(nodeInfo);  }); -router.get("/.well-known/nodeinfo/2.2", async (req, res) => { -    const eventCount = await Event.countDocuments(); +router.get( +    "/.well-known/nodeinfo/2.2", +    send404IfNotFederated, +    async (req, res) => { +        const eventCount = await Event.countDocuments(); -    if (!res.locals.config?.general.is_federated) { -        return res.status(404).render("404", frontendConfig(res)); -    } -    const nodeInfo = { -        version: "2.2", -        instance: { -            name: res.locals.config?.general.site_name, -            description: -                "Federated, no-registration, privacy-respecting event hosting.", -        }, -        software: { -            name: "Gathio", -            version: process.env.npm_package_version || "unknown", -            repository: "https://github.com/lowercasename/gathio", -            homepage: "https://gath.io", -        }, -        protocols: ["activitypub"], -        services: { -            inbound: [], -            outbound: [], -        }, -        openRegistrations: true, -        usage: { -            users: { -                total: eventCount, +        if (!res.locals.config?.general.is_federated) { +            return res.status(404).render("404", frontendConfig(res)); +        } +        const nodeInfo = { +            version: "2.2", +            instance: { +                name: res.locals.config?.general.site_name, +                description: +                    "Federated, no-registration, privacy-respecting event hosting.",              }, -        }, -    }; -    res.header( -        "Content-Type", -        'application/json; profile="http://nodeinfo.diaspora.software/ns/schema/2.1#"', -    ).send(nodeInfo); -}); - -router.get("/.well-known/webfinger", async (req, res) => { -    let resource = req.query.resource as string; -    if (!resource || !resource.includes("acct:")) { -        return res -            .status(400) -            .send( -                'Bad request. Please make sure "acct:USER@DOMAIN" is what you are sending as the "resource" query parameter.', -            ); -    } else { -        // "foo@domain" -        let activityPubAccount = resource.replace("acct:", ""); -        // "foo" -        let eventID = activityPubAccount.replace(/@.*/, ""); +            software: { +                name: "Gathio", +                version: process.env.npm_package_version || "unknown", +                repository: "https://github.com/lowercasename/gathio", +                homepage: "https://gath.io", +            }, +            protocols: ["activitypub"], +            services: { +                inbound: [], +                outbound: [], +            }, +            openRegistrations: true, +            usage: { +                users: { +                    total: eventCount, +                }, +            }, +        }; +        res.header( +            "Content-Type", +            'application/json; profile="http://nodeinfo.diaspora.software/ns/schema/2.1#"', +        ).send(nodeInfo); +    }, +); + +router.get( +    "/.well-known/webfinger", +    send404IfNotFederated, +    async (req, res) => { +        let resource = req.query.resource as string; +        if (!resource || !resource.includes("acct:")) { +            return res +                .status(400) +                .send( +                    'Bad request. Please make sure "acct:USER@DOMAIN" is what you are sending as the "resource" query parameter.', +                ); +        } else { +            // "foo@domain" +            let activityPubAccount = resource.replace("acct:", ""); +            // "foo" +            let eventID = activityPubAccount.replace(/@.*/, ""); -        try { -            const event = await Event.findOne({ id: eventID }); +            try { +                const event = await Event.findOne({ id: eventID }); -            if (!event) { -                return res.status(404).render("404", frontendConfig(res)); -            } else { -                if (acceptsActivityPub(req)) { -                    res.header( -                        "Content-Type", -                        "application/activity+json", -                    ).send( -                        createWebfinger( -                            eventID, -                            res.locals.config?.general.domain, -                        ), -                    ); +                if (!event) { +                    return res.status(404).render("404", frontendConfig(res));                  } else { -                    res.header("Content-Type", "application/json").send( -                        createWebfinger( -                            eventID, -                            res.locals.config?.general.domain, -                        ), -                    ); +                    if (acceptsActivityPub(req)) { +                        res.header( +                            "Content-Type", +                            "application/activity+json", +                        ).send( +                            createWebfinger( +                                eventID, +                                res.locals.config?.general.domain, +                            ), +                        ); +                    } else { +                        res.header("Content-Type", "application/json").send( +                            createWebfinger( +                                eventID, +                                res.locals.config?.general.domain, +                            ), +                        ); +                    }                  } +            } catch (err) { +                addToLog( +                    "renderWebfinger", +                    "error", +                    `Attempt to render webfinger for ${resource} failed with error: ${err}`, +                ); +                return res.status(404).render("404", frontendConfig(res));              } -        } catch (err) { -            addToLog( -                "renderWebfinger", -                "error", -                `Attempt to render webfinger for ${resource} failed with error: ${err}`, -            ); -            return res.status(404).render("404", frontendConfig(res));          } -    } -}); +    }, +); -router.get("/:eventID/followers", async (req, res) => { +router.get("/:eventID/followers", send404IfNotFederated, async (req, res) => {      const eventID = req.params.eventID;      try {  | 
