@rmdes/indiekit-endpoint-activitypub 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -84,9 +84,36 @@ export default class ActivityPubEndpoint {
84
84
 
85
85
  router.use((req, res, next) => {
86
86
  if (!self._fedifyMiddleware) return next();
87
+ // Skip Fedify for admin UI routes — they're handled by the
88
+ // authenticated `routes` getter, not the federation layer.
89
+ if (req.path.startsWith("/admin")) return next();
87
90
  return self._fedifyMiddleware(req, res, next);
88
91
  });
89
92
 
93
+ // Catch-all for federation paths that Fedify didn't handle (e.g. GET
94
+ // on inbox). Without this, they fall through to Indiekit's auth
95
+ // middleware and redirect to the login page.
96
+ router.all("/users/:identifier/inbox", (req, res) => {
97
+ res
98
+ .status(405)
99
+ .set("Allow", "POST")
100
+ .type("application/activity+json")
101
+ .json({
102
+ error: "Method Not Allowed",
103
+ message: "The inbox only accepts POST requests",
104
+ });
105
+ });
106
+ router.all("/inbox", (req, res) => {
107
+ res
108
+ .status(405)
109
+ .set("Allow", "POST")
110
+ .type("application/activity+json")
111
+ .json({
112
+ error: "Method Not Allowed",
113
+ message: "The shared inbox only accepts POST requests",
114
+ });
115
+ });
116
+
90
117
  return router;
91
118
  }
92
119
 
@@ -7,14 +7,18 @@
7
7
 
8
8
  import {
9
9
  Accept,
10
+ Add,
10
11
  Announce,
12
+ Block,
11
13
  Create,
12
14
  Delete,
13
15
  Follow,
14
16
  Like,
15
17
  Move,
16
18
  Note,
19
+ Remove,
17
20
  Undo,
21
+ Update,
18
22
  } from "@fedify/fedify";
19
23
 
20
24
  /**
@@ -201,6 +205,46 @@ export function registerInboxListeners(inboxChain, options) {
201
205
  objectUrl: newActorUrl,
202
206
  summary: `${oldActorUrl} moved to ${newActorUrl}`,
203
207
  });
208
+ })
209
+ .on(Update, async (ctx, update) => {
210
+ // Remote actor updated their profile — refresh stored follower data
211
+ const actorObj = await update.getActor();
212
+ const actorUrl = actorObj?.id?.href || "";
213
+ if (!actorUrl) return;
214
+
215
+ const existing = await collections.ap_followers.findOne({ actorUrl });
216
+ if (existing) {
217
+ await collections.ap_followers.updateOne(
218
+ { actorUrl },
219
+ {
220
+ $set: {
221
+ name:
222
+ actorObj.name?.toString() ||
223
+ actorObj.preferredUsername?.toString() ||
224
+ actorUrl,
225
+ handle: actorObj.preferredUsername?.toString() || "",
226
+ avatar: actorObj.icon
227
+ ? (await actorObj.icon)?.url?.href || ""
228
+ : "",
229
+ updatedAt: new Date().toISOString(),
230
+ },
231
+ },
232
+ );
233
+ }
234
+ })
235
+ .on(Block, async (ctx, block) => {
236
+ // Remote actor blocked us — remove them from followers
237
+ const actorObj = await block.getActor();
238
+ const actorUrl = actorObj?.id?.href || "";
239
+ if (actorUrl) {
240
+ await collections.ap_followers.deleteOne({ actorUrl });
241
+ }
242
+ })
243
+ .on(Add, async () => {
244
+ // Mastodon uses Add for pinning posts to featured collections — safe to ignore
245
+ })
246
+ .on(Remove, async () => {
247
+ // Mastodon uses Remove for unpinning posts from featured collections — safe to ignore
204
248
  });
205
249
  }
206
250
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-activitypub",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
5
5
  "keywords": [
6
6
  "indiekit",