@rmdes/indiekit-endpoint-activitypub 1.0.13 → 1.0.15

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.
@@ -233,23 +233,32 @@ async function processOneFollow(options, entry) {
233
233
  throw new Error("Could not resolve remote actor");
234
234
  }
235
235
 
236
- // Send Follow activity
236
+ // Use the canonical actor URL (may differ from imported URL)
237
+ const canonicalUrl = remoteActor.id?.href || entry.actorUrl;
238
+
239
+ // Send Follow activity using canonical URL
237
240
  const follow = new Follow({
238
241
  actor: ctx.getActorUri(handle),
239
- object: new URL(entry.actorUrl),
242
+ object: new URL(canonicalUrl),
240
243
  });
241
244
 
242
245
  await ctx.sendActivity({ identifier: handle }, remoteActor, follow);
243
246
 
244
- // Mark as sent
247
+ // Mark as sent — update actorUrl to canonical form so Accept handler
248
+ // can match when the remote server responds
249
+ const updateFields = {
250
+ source: "refollow:sent",
251
+ refollowLastAttempt: new Date().toISOString(),
252
+ refollowError: null,
253
+ };
254
+ if (canonicalUrl !== entry.actorUrl) {
255
+ updateFields.actorUrl = canonicalUrl;
256
+ }
257
+
245
258
  await collections.ap_following.updateOne(
246
259
  { _id: entry._id },
247
260
  {
248
- $set: {
249
- source: "refollow:sent",
250
- refollowLastAttempt: new Date().toISOString(),
251
- refollowError: null,
252
- },
261
+ $set: updateFields,
253
262
  $inc: { refollowAttempts: 1 },
254
263
  },
255
264
  );
@@ -125,8 +125,23 @@ export function registerInboxListeners(inboxChain, options) {
125
125
  const actorUrl = actorObj?.id?.href || "";
126
126
  if (!actorUrl) return;
127
127
 
128
- const inner = await accept.getObject();
129
- if (!(inner instanceof Follow)) return;
128
+ // Check if the inner object is a Follow. Some servers send the full
129
+ // Follow object, others send only a reference URL that Fedify can't
130
+ // resolve (since the original Follow was our outgoing activity).
131
+ let isFollow = false;
132
+ try {
133
+ const inner = await accept.getObject();
134
+ isFollow = inner instanceof Follow;
135
+ // If inner resolved to a non-Follow activity, skip
136
+ if (inner && !isFollow) {
137
+ console.info(
138
+ `[ActivityPub] Accept from ${actorUrl}: inner is ${inner.constructor?.name}, not Follow — skipping`,
139
+ );
140
+ return;
141
+ }
142
+ } catch {
143
+ // getObject() failed — proceed anyway if we have a pending follow
144
+ }
130
145
 
131
146
  // Match against our following list for refollow or microsub-reader follows
132
147
  const result = await collections.ap_following.findOneAndUpdate(
@@ -161,13 +176,18 @@ export function registerInboxListeners(inboxChain, options) {
161
176
  }
162
177
  })
163
178
  .on(Like, async (ctx, like) => {
179
+ const objectId = (await like.getObject())?.id?.href || "";
180
+
181
+ // Only log likes of our own content
182
+ const pubUrl = collections._publicationUrl;
183
+ if (!objectId || (pubUrl && !objectId.startsWith(pubUrl))) return;
184
+
164
185
  const actorObj = await like.getActor();
165
186
  const actorUrl = actorObj?.id?.href || "";
166
187
  const actorName =
167
188
  actorObj?.name?.toString() ||
168
189
  actorObj?.preferredUsername?.toString() ||
169
190
  actorUrl;
170
- const objectId = (await like.getObject())?.id?.href || "";
171
191
 
172
192
  await logActivity(collections, storeRawActivities, {
173
193
  direction: "inbound",
@@ -179,13 +199,18 @@ export function registerInboxListeners(inboxChain, options) {
179
199
  });
180
200
  })
181
201
  .on(Announce, async (ctx, announce) => {
202
+ const objectId = (await announce.getObject())?.id?.href || "";
203
+
204
+ // Only log boosts of our own content
205
+ const pubUrl = collections._publicationUrl;
206
+ if (!objectId || (pubUrl && !objectId.startsWith(pubUrl))) return;
207
+
182
208
  const actorObj = await announce.getActor();
183
209
  const actorUrl = actorObj?.id?.href || "";
184
210
  const actorName =
185
211
  actorObj?.name?.toString() ||
186
212
  actorObj?.preferredUsername?.toString() ||
187
213
  actorUrl;
188
- const objectId = (await announce.getObject())?.id?.href || "";
189
214
 
190
215
  await logActivity(collections, storeRawActivities, {
191
216
  direction: "inbound",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-activitypub",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
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",