@fedify/relay 2.0.0-pr.471.1909 → 2.0.0-pr.471.1921

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.
Files changed (3) hide show
  1. package/dist/mod.cjs +58 -25
  2. package/dist/mod.js +58 -25
  3. package/package.json +4 -4
package/dist/mod.cjs CHANGED
@@ -120,21 +120,21 @@ var MastodonRelay = class {
120
120
  const isPublicFollow = follow.objectId.href === "https://www.w3.org/ns/activitystreams#Public";
121
121
  if (!isPublicFollow && parsed?.type !== "actor") return;
122
122
  const relayActorUri = ctx.getActorUri(RELAY_SERVER_ACTOR);
123
- const recipient = await follow.getActor(ctx);
124
- if (recipient == null || recipient.id == null || recipient.preferredUsername == null || recipient.inboxId == null) return;
123
+ const follower = await follow.getActor(ctx);
124
+ if (follower == null || follower.id == null || follower.preferredUsername == null || follower.inboxId == null) return;
125
125
  let approved = false;
126
- if (this.#subscriptionHandler) approved = await this.#subscriptionHandler(ctx, recipient);
126
+ if (this.#subscriptionHandler) approved = await this.#subscriptionHandler(ctx, follower);
127
127
  if (approved) {
128
128
  const followers = await options.kv.get(["followers"]) ?? [];
129
129
  followers.push(follow.id.href);
130
130
  await options.kv.set(["followers"], followers);
131
- await options.kv.set(["follower", follow.id.href], await recipient.toJsonLd());
132
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new __fedify_fedify_vocab.Accept({
131
+ await options.kv.set(["follower", follow.id.href], await follower.toJsonLd());
132
+ await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new __fedify_fedify_vocab.Accept({
133
133
  id: new URL(`#accepts`, relayActorUri),
134
134
  actor: relayActorUri,
135
135
  object: follow
136
136
  }));
137
- } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new __fedify_fedify_vocab.Reject({
137
+ } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new __fedify_fedify_vocab.Reject({
138
138
  id: new URL(`#rejects`, relayActorUri),
139
139
  actor: relayActorUri,
140
140
  object: follow
@@ -226,6 +226,7 @@ var LitePubRelay = class {
226
226
  summary: "LitePub-compatible ActivityPub relay server",
227
227
  inbox: ctx.getInboxUri(),
228
228
  followers: ctx.getFollowersUri(identifier),
229
+ following: ctx.getFollowingUri(identifier),
229
230
  url: ctx.getActorUri(identifier),
230
231
  publicKey: keys[0].cryptographicKey,
231
232
  assertionMethods: keys.map((k) => k.multikey)
@@ -273,6 +274,19 @@ var LitePubRelay = class {
273
274
  };
274
275
  return [rsaPair, ed25519Pair];
275
276
  });
277
+ this.#federation.setFollowingDispatcher("/users/{identifier}/following", async (_ctx, identifier) => {
278
+ if (identifier !== RELAY_SERVER_ACTOR) return null;
279
+ const followers = await options.kv.get(["followers"]) ?? [];
280
+ const actors = [];
281
+ for (const followerId of followers) {
282
+ const follower = await options.kv.get(["follower", followerId]);
283
+ if (!follower) continue;
284
+ const actor = await __fedify_fedify_vocab.Object.fromJsonLd(follower.actor);
285
+ if (!(0, __fedify_fedify_vocab.isActor)(actor)) continue;
286
+ actors.push(actor);
287
+ }
288
+ return { items: actors };
289
+ });
276
290
  this.#federation.setFollowersDispatcher("/users/{identifier}/followers", async (_ctx, identifier) => {
277
291
  if (identifier !== RELAY_SERVER_ACTOR) return null;
278
292
  const followers = await options.kv.get(["followers"]) ?? [];
@@ -292,53 +306,59 @@ var LitePubRelay = class {
292
306
  const isPublicFollow = follow.objectId.href === "https://www.w3.org/ns/activitystreams#Public";
293
307
  if (!isPublicFollow && parsed?.type !== "actor") return;
294
308
  const relayActorUri = ctx.getActorUri(RELAY_SERVER_ACTOR);
295
- const recipient = await follow.getActor(ctx);
296
- if (recipient == null || recipient.id == null || recipient.preferredUsername == null || recipient.inboxId == null) return;
297
- const existingFollow = await options.kv.get(["follower", recipient.id.href]);
309
+ const follower = await follow.getActor(ctx);
310
+ if (follower == null || follower.id == null || follower.preferredUsername == null || follower.inboxId == null) return;
311
+ const existingFollow = await options.kv.get(["follower", follower.id.href]);
298
312
  if (existingFollow?.state === "pending") return;
299
313
  let subscriptionApproved = false;
300
- if (this.#subscriptionHandler) subscriptionApproved = await this.#subscriptionHandler(ctx, recipient);
314
+ if (this.#subscriptionHandler) subscriptionApproved = await this.#subscriptionHandler(ctx, follower);
301
315
  if (subscriptionApproved) {
302
- await options.kv.set(["follower", recipient.id.href], {
303
- "actor": await recipient.toJsonLd(),
316
+ await options.kv.set(["follower", follower.id.href], {
317
+ "actor": await follower.toJsonLd(),
304
318
  "state": "pending"
305
319
  });
306
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new __fedify_fedify_vocab.Accept({
320
+ await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new __fedify_fedify_vocab.Accept({
307
321
  id: new URL(`#accepts`, relayActorUri),
308
322
  actor: relayActorUri,
309
323
  object: follow
310
324
  }));
311
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new __fedify_fedify_vocab.Follow({
325
+ await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new __fedify_fedify_vocab.Follow({
312
326
  actor: relayActorUri,
313
- object: recipient.id,
314
- to: recipient.id
327
+ object: follower.id,
328
+ to: follower.id
315
329
  }));
316
- } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new __fedify_fedify_vocab.Reject({
330
+ } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new __fedify_fedify_vocab.Reject({
317
331
  id: new URL(`#rejects`, relayActorUri),
318
332
  actor: relayActorUri,
319
333
  object: follow
320
334
  }));
321
335
  }).on(__fedify_fedify_vocab.Accept, async (ctx, accept) => {
322
- const follow = await accept.getObject();
336
+ const follow = await accept.getObject({
337
+ crossOrigin: "trust",
338
+ ...ctx
339
+ });
323
340
  if (!(follow instanceof __fedify_fedify_vocab.Follow)) return;
324
- const following = await accept.getActor();
325
- if (!(0, __fedify_fedify_vocab.isActor)(following)) return;
326
341
  const follower = follow.actorId;
327
342
  if (follower == null) return;
343
+ const following = await accept.getActor();
344
+ if (!(0, __fedify_fedify_vocab.isActor)(following) || !following.id) return;
328
345
  const parsed = ctx.parseUri(follower);
329
346
  if (parsed == null || parsed.type !== "actor") return;
330
- const followerData = await options.kv.get(["follower", follower.href]);
347
+ const followerData = await options.kv.get(["follower", following.id.href]);
331
348
  if (followerData == null) return;
332
349
  const updatedFollowerData = {
333
350
  ...followerData,
334
- status: "accepted"
351
+ state: "accepted"
335
352
  };
336
- await options.kv.set(["follower", follower.href], updatedFollowerData);
353
+ await options.kv.set(["follower", following.id.href], updatedFollowerData);
337
354
  const followers = await options.kv.get(["followers"]) ?? [];
338
- followers.push(follower.href);
355
+ followers.push(following.id.href);
339
356
  await options.kv.set(["followers"], followers);
340
357
  }).on(__fedify_fedify_vocab.Undo, async (ctx, undo) => {
341
- const activity = await undo.getObject(ctx);
358
+ const activity = await undo.getObject({
359
+ crossOrigin: "trust",
360
+ ...ctx
361
+ });
342
362
  if (activity instanceof __fedify_fedify_vocab.Follow) {
343
363
  if (activity.id == null || activity.actorId == null) return;
344
364
  const followers = await options.kv.get(["followers"]) ?? [];
@@ -402,6 +422,19 @@ var LitePubRelay = class {
402
422
  excludeBaseUris,
403
423
  preferSharedInbox: true
404
424
  });
425
+ }).on(__fedify_fedify_vocab.Announce, async (ctx, announceActivity) => {
426
+ const sender = await announceActivity.getActor(ctx);
427
+ const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
428
+ const announce = new __fedify_fedify_vocab.Announce({
429
+ id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
430
+ actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
431
+ object: announceActivity.objectId,
432
+ to: __fedify_fedify_vocab.PUBLIC_COLLECTION
433
+ });
434
+ await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
435
+ excludeBaseUris,
436
+ preferSharedInbox: true
437
+ });
405
438
  });
406
439
  }
407
440
  get domain() {
package/dist/mod.js CHANGED
@@ -97,21 +97,21 @@ var MastodonRelay = class {
97
97
  const isPublicFollow = follow.objectId.href === "https://www.w3.org/ns/activitystreams#Public";
98
98
  if (!isPublicFollow && parsed?.type !== "actor") return;
99
99
  const relayActorUri = ctx.getActorUri(RELAY_SERVER_ACTOR);
100
- const recipient = await follow.getActor(ctx);
101
- if (recipient == null || recipient.id == null || recipient.preferredUsername == null || recipient.inboxId == null) return;
100
+ const follower = await follow.getActor(ctx);
101
+ if (follower == null || follower.id == null || follower.preferredUsername == null || follower.inboxId == null) return;
102
102
  let approved = false;
103
- if (this.#subscriptionHandler) approved = await this.#subscriptionHandler(ctx, recipient);
103
+ if (this.#subscriptionHandler) approved = await this.#subscriptionHandler(ctx, follower);
104
104
  if (approved) {
105
105
  const followers = await options.kv.get(["followers"]) ?? [];
106
106
  followers.push(follow.id.href);
107
107
  await options.kv.set(["followers"], followers);
108
- await options.kv.set(["follower", follow.id.href], await recipient.toJsonLd());
109
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new Accept({
108
+ await options.kv.set(["follower", follow.id.href], await follower.toJsonLd());
109
+ await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new Accept({
110
110
  id: new URL(`#accepts`, relayActorUri),
111
111
  actor: relayActorUri,
112
112
  object: follow
113
113
  }));
114
- } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new Reject({
114
+ } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new Reject({
115
115
  id: new URL(`#rejects`, relayActorUri),
116
116
  actor: relayActorUri,
117
117
  object: follow
@@ -203,6 +203,7 @@ var LitePubRelay = class {
203
203
  summary: "LitePub-compatible ActivityPub relay server",
204
204
  inbox: ctx.getInboxUri(),
205
205
  followers: ctx.getFollowersUri(identifier),
206
+ following: ctx.getFollowingUri(identifier),
206
207
  url: ctx.getActorUri(identifier),
207
208
  publicKey: keys[0].cryptographicKey,
208
209
  assertionMethods: keys.map((k) => k.multikey)
@@ -250,6 +251,19 @@ var LitePubRelay = class {
250
251
  };
251
252
  return [rsaPair, ed25519Pair];
252
253
  });
254
+ this.#federation.setFollowingDispatcher("/users/{identifier}/following", async (_ctx, identifier) => {
255
+ if (identifier !== RELAY_SERVER_ACTOR) return null;
256
+ const followers = await options.kv.get(["followers"]) ?? [];
257
+ const actors = [];
258
+ for (const followerId of followers) {
259
+ const follower = await options.kv.get(["follower", followerId]);
260
+ if (!follower) continue;
261
+ const actor = await Object$1.fromJsonLd(follower.actor);
262
+ if (!isActor(actor)) continue;
263
+ actors.push(actor);
264
+ }
265
+ return { items: actors };
266
+ });
253
267
  this.#federation.setFollowersDispatcher("/users/{identifier}/followers", async (_ctx, identifier) => {
254
268
  if (identifier !== RELAY_SERVER_ACTOR) return null;
255
269
  const followers = await options.kv.get(["followers"]) ?? [];
@@ -269,53 +283,59 @@ var LitePubRelay = class {
269
283
  const isPublicFollow = follow.objectId.href === "https://www.w3.org/ns/activitystreams#Public";
270
284
  if (!isPublicFollow && parsed?.type !== "actor") return;
271
285
  const relayActorUri = ctx.getActorUri(RELAY_SERVER_ACTOR);
272
- const recipient = await follow.getActor(ctx);
273
- if (recipient == null || recipient.id == null || recipient.preferredUsername == null || recipient.inboxId == null) return;
274
- const existingFollow = await options.kv.get(["follower", recipient.id.href]);
286
+ const follower = await follow.getActor(ctx);
287
+ if (follower == null || follower.id == null || follower.preferredUsername == null || follower.inboxId == null) return;
288
+ const existingFollow = await options.kv.get(["follower", follower.id.href]);
275
289
  if (existingFollow?.state === "pending") return;
276
290
  let subscriptionApproved = false;
277
- if (this.#subscriptionHandler) subscriptionApproved = await this.#subscriptionHandler(ctx, recipient);
291
+ if (this.#subscriptionHandler) subscriptionApproved = await this.#subscriptionHandler(ctx, follower);
278
292
  if (subscriptionApproved) {
279
- await options.kv.set(["follower", recipient.id.href], {
280
- "actor": await recipient.toJsonLd(),
293
+ await options.kv.set(["follower", follower.id.href], {
294
+ "actor": await follower.toJsonLd(),
281
295
  "state": "pending"
282
296
  });
283
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new Accept({
297
+ await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new Accept({
284
298
  id: new URL(`#accepts`, relayActorUri),
285
299
  actor: relayActorUri,
286
300
  object: follow
287
301
  }));
288
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new Follow({
302
+ await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new Follow({
289
303
  actor: relayActorUri,
290
- object: recipient.id,
291
- to: recipient.id
304
+ object: follower.id,
305
+ to: follower.id
292
306
  }));
293
- } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new Reject({
307
+ } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, follower, new Reject({
294
308
  id: new URL(`#rejects`, relayActorUri),
295
309
  actor: relayActorUri,
296
310
  object: follow
297
311
  }));
298
312
  }).on(Accept, async (ctx, accept) => {
299
- const follow = await accept.getObject();
313
+ const follow = await accept.getObject({
314
+ crossOrigin: "trust",
315
+ ...ctx
316
+ });
300
317
  if (!(follow instanceof Follow)) return;
301
- const following = await accept.getActor();
302
- if (!isActor(following)) return;
303
318
  const follower = follow.actorId;
304
319
  if (follower == null) return;
320
+ const following = await accept.getActor();
321
+ if (!isActor(following) || !following.id) return;
305
322
  const parsed = ctx.parseUri(follower);
306
323
  if (parsed == null || parsed.type !== "actor") return;
307
- const followerData = await options.kv.get(["follower", follower.href]);
324
+ const followerData = await options.kv.get(["follower", following.id.href]);
308
325
  if (followerData == null) return;
309
326
  const updatedFollowerData = {
310
327
  ...followerData,
311
- status: "accepted"
328
+ state: "accepted"
312
329
  };
313
- await options.kv.set(["follower", follower.href], updatedFollowerData);
330
+ await options.kv.set(["follower", following.id.href], updatedFollowerData);
314
331
  const followers = await options.kv.get(["followers"]) ?? [];
315
- followers.push(follower.href);
332
+ followers.push(following.id.href);
316
333
  await options.kv.set(["followers"], followers);
317
334
  }).on(Undo, async (ctx, undo) => {
318
- const activity = await undo.getObject(ctx);
335
+ const activity = await undo.getObject({
336
+ crossOrigin: "trust",
337
+ ...ctx
338
+ });
319
339
  if (activity instanceof Follow) {
320
340
  if (activity.id == null || activity.actorId == null) return;
321
341
  const followers = await options.kv.get(["followers"]) ?? [];
@@ -379,6 +399,19 @@ var LitePubRelay = class {
379
399
  excludeBaseUris,
380
400
  preferSharedInbox: true
381
401
  });
402
+ }).on(Announce, async (ctx, announceActivity) => {
403
+ const sender = await announceActivity.getActor(ctx);
404
+ const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
405
+ const announce = new Announce({
406
+ id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
407
+ actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
408
+ object: announceActivity.objectId,
409
+ to: PUBLIC_COLLECTION
410
+ });
411
+ await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
412
+ excludeBaseUris,
413
+ preferSharedInbox: true
414
+ });
382
415
  });
383
416
  }
384
417
  get domain() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/relay",
3
- "version": "2.0.0-pr.471.1909+976b008d",
3
+ "version": "2.0.0-pr.471.1921+0a8b8dcb",
4
4
  "description": "ActivityPub relay support for Fedify",
5
5
  "keywords": [
6
6
  "Fedify",
@@ -48,13 +48,13 @@
48
48
  "package.json"
49
49
  ],
50
50
  "peerDependencies": {
51
- "@fedify/fedify": "^2.0.0-pr.471.1909+976b008d"
51
+ "@fedify/fedify": "^2.0.0-pr.471.1921+0a8b8dcb"
52
52
  },
53
53
  "devDependencies": {
54
54
  "tsdown": "^0.12.9",
55
55
  "typescript": "^5.9.3",
56
- "@fedify/testing": "^2.0.0-pr.471.1909+976b008d",
57
- "@fedify/vocab-runtime": "^2.0.0-pr.471.1909+976b008d"
56
+ "@fedify/testing": "^2.0.0-pr.471.1921+0a8b8dcb",
57
+ "@fedify/vocab-runtime": "^2.0.0-pr.471.1921+0a8b8dcb"
58
58
  },
59
59
  "scripts": {
60
60
  "build": "deno task codegen && tsdown",