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

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 +1 -193
  2. package/dist/mod.js +2 -194
  3. package/package.json +4 -4
package/dist/mod.cjs CHANGED
@@ -210,199 +210,7 @@ var LitePubRelay = class {
210
210
  #subscriptionHandler;
211
211
  constructor(options) {
212
212
  this.#options = options;
213
- this.#federation = options.federation ?? (0, __fedify_fedify.createFederation)({
214
- kv: options.kv,
215
- queue: options.queue,
216
- documentLoaderFactory: options.documentLoaderFactory,
217
- authenticatedDocumentLoaderFactory: options.authenticatedDocumentLoaderFactory
218
- });
219
- this.#federation.setActorDispatcher("/users/{identifier}", async (ctx, identifier) => {
220
- if (identifier !== RELAY_SERVER_ACTOR) return null;
221
- const keys = await ctx.getActorKeyPairs(identifier);
222
- return new __fedify_fedify_vocab.Application({
223
- id: ctx.getActorUri(identifier),
224
- preferredUsername: identifier,
225
- name: "ActivityPub Relay",
226
- summary: "LitePub-compatible ActivityPub relay server",
227
- inbox: ctx.getInboxUri(),
228
- followers: ctx.getFollowersUri(identifier),
229
- url: ctx.getActorUri(identifier),
230
- publicKey: keys[0].cryptographicKey,
231
- assertionMethods: keys.map((k) => k.multikey)
232
- });
233
- }).setKeyPairsDispatcher(async (_ctx, identifier) => {
234
- if (identifier !== RELAY_SERVER_ACTOR) return [];
235
- const rsaPairJson = await options.kv.get([
236
- "keypair",
237
- "rsa",
238
- identifier
239
- ]);
240
- const ed25519PairJson = await options.kv.get([
241
- "keypair",
242
- "ed25519",
243
- identifier
244
- ]);
245
- if (rsaPairJson == null || ed25519PairJson == null) {
246
- const rsaPair$1 = await (0, __fedify_fedify.generateCryptoKeyPair)("RSASSA-PKCS1-v1_5");
247
- const ed25519Pair$1 = await (0, __fedify_fedify.generateCryptoKeyPair)("Ed25519");
248
- await options.kv.set([
249
- "keypair",
250
- "rsa",
251
- identifier
252
- ], {
253
- privateKey: await (0, __fedify_fedify.exportJwk)(rsaPair$1.privateKey),
254
- publicKey: await (0, __fedify_fedify.exportJwk)(rsaPair$1.publicKey)
255
- });
256
- await options.kv.set([
257
- "keypair",
258
- "ed25519",
259
- identifier
260
- ], {
261
- privateKey: await (0, __fedify_fedify.exportJwk)(ed25519Pair$1.privateKey),
262
- publicKey: await (0, __fedify_fedify.exportJwk)(ed25519Pair$1.publicKey)
263
- });
264
- return [rsaPair$1, ed25519Pair$1];
265
- }
266
- const rsaPair = {
267
- privateKey: await (0, __fedify_fedify.importJwk)(rsaPairJson.privateKey, "private"),
268
- publicKey: await (0, __fedify_fedify.importJwk)(rsaPairJson.publicKey, "public")
269
- };
270
- const ed25519Pair = {
271
- privateKey: await (0, __fedify_fedify.importJwk)(ed25519PairJson.privateKey, "private"),
272
- publicKey: await (0, __fedify_fedify.importJwk)(ed25519PairJson.publicKey, "public")
273
- };
274
- return [rsaPair, ed25519Pair];
275
- });
276
- this.#federation.setFollowersDispatcher("/users/{identifier}/followers", async (_ctx, identifier) => {
277
- if (identifier !== RELAY_SERVER_ACTOR) return null;
278
- const followers = await options.kv.get(["followers"]) ?? [];
279
- const actors = [];
280
- for (const followerId of followers) {
281
- const follower = await options.kv.get(["follower", followerId]);
282
- if (!follower) continue;
283
- const actor = await __fedify_fedify_vocab.Object.fromJsonLd(follower.actor);
284
- if (!(0, __fedify_fedify_vocab.isActor)(actor)) continue;
285
- actors.push(actor);
286
- }
287
- return { items: actors };
288
- });
289
- this.#federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(__fedify_fedify_vocab.Follow, async (ctx, follow) => {
290
- if (follow.id == null || follow.objectId == null) return;
291
- const parsed = ctx.parseUri(follow.objectId);
292
- const isPublicFollow = follow.objectId.href === "https://www.w3.org/ns/activitystreams#Public";
293
- if (!isPublicFollow && parsed?.type !== "actor") return;
294
- 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]);
298
- if (existingFollow?.state === "pending") return;
299
- let subscriptionApproved = false;
300
- if (this.#subscriptionHandler) subscriptionApproved = await this.#subscriptionHandler(ctx, recipient);
301
- if (subscriptionApproved) {
302
- await options.kv.set(["follower", recipient.id.href], {
303
- "actor": await recipient.toJsonLd(),
304
- "state": "pending"
305
- });
306
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new __fedify_fedify_vocab.Accept({
307
- id: new URL(`#accepts`, relayActorUri),
308
- actor: relayActorUri,
309
- object: follow
310
- }));
311
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new __fedify_fedify_vocab.Follow({
312
- actor: relayActorUri,
313
- object: recipient.id,
314
- to: recipient.id
315
- }));
316
- } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new __fedify_fedify_vocab.Reject({
317
- id: new URL(`#rejects`, relayActorUri),
318
- actor: relayActorUri,
319
- object: follow
320
- }));
321
- }).on(__fedify_fedify_vocab.Accept, async (ctx, accept) => {
322
- const follow = await accept.getObject();
323
- if (!(follow instanceof __fedify_fedify_vocab.Follow)) return;
324
- const following = await accept.getActor();
325
- if (!(0, __fedify_fedify_vocab.isActor)(following)) return;
326
- const follower = follow.actorId;
327
- if (follower == null) return;
328
- const parsed = ctx.parseUri(follower);
329
- if (parsed == null || parsed.type !== "actor") return;
330
- const followerData = await options.kv.get(["follower", follower.href]);
331
- if (followerData == null) return;
332
- const updatedFollowerData = {
333
- ...followerData,
334
- status: "accepted"
335
- };
336
- await options.kv.set(["follower", follower.href], updatedFollowerData);
337
- const followers = await options.kv.get(["followers"]) ?? [];
338
- followers.push(follower.href);
339
- await options.kv.set(["followers"], followers);
340
- }).on(__fedify_fedify_vocab.Undo, async (ctx, undo) => {
341
- const activity = await undo.getObject(ctx);
342
- if (activity instanceof __fedify_fedify_vocab.Follow) {
343
- if (activity.id == null || activity.actorId == null) return;
344
- const followers = await options.kv.get(["followers"]) ?? [];
345
- const updatedFollowers = followers.filter((id) => id !== activity.actorId?.href);
346
- await options.kv.set(["followers"], updatedFollowers);
347
- options.kv.delete(["follower", activity.actorId?.href]);
348
- } else console.warn("Unsupported object type ({type}) for Undo activity: {object}", {
349
- type: activity?.constructor.name,
350
- object: activity
351
- });
352
- }).on(__fedify_fedify_vocab.Create, async (ctx, create) => {
353
- const sender = await create.getActor(ctx);
354
- const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
355
- const announce = new __fedify_fedify_vocab.Announce({
356
- id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
357
- actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
358
- object: create.objectId,
359
- to: __fedify_fedify_vocab.PUBLIC_COLLECTION,
360
- published: Temporal.Now.instant()
361
- });
362
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
363
- excludeBaseUris,
364
- preferSharedInbox: true
365
- });
366
- }).on(__fedify_fedify_vocab.Update, async (ctx, update) => {
367
- const sender = await update.getActor(ctx);
368
- const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
369
- const announce = new __fedify_fedify_vocab.Announce({
370
- id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
371
- actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
372
- object: update.objectId,
373
- to: __fedify_fedify_vocab.PUBLIC_COLLECTION
374
- });
375
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
376
- excludeBaseUris,
377
- preferSharedInbox: true
378
- });
379
- }).on(__fedify_fedify_vocab.Move, async (ctx, move) => {
380
- const sender = await move.getActor(ctx);
381
- const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
382
- const announce = new __fedify_fedify_vocab.Announce({
383
- id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
384
- actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
385
- object: move.objectId,
386
- to: __fedify_fedify_vocab.PUBLIC_COLLECTION
387
- });
388
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
389
- excludeBaseUris,
390
- preferSharedInbox: true
391
- });
392
- }).on(__fedify_fedify_vocab.Delete, async (ctx, deleteActivity) => {
393
- const sender = await deleteActivity.getActor(ctx);
394
- const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
395
- const announce = new __fedify_fedify_vocab.Announce({
396
- id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
397
- actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
398
- object: deleteActivity.objectId,
399
- to: __fedify_fedify_vocab.PUBLIC_COLLECTION
400
- });
401
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
402
- excludeBaseUris,
403
- preferSharedInbox: true
404
- });
405
- });
213
+ this.#federation = (0, __fedify_fedify.createFederation)({ kv: options.kv });
406
214
  }
407
215
  get domain() {
408
216
  return this.#options.domain || "localhost";
package/dist/mod.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createFederation, exportJwk, generateCryptoKeyPair, importJwk } from "@fedify/fedify";
2
- import { Accept, Announce, Application, Create, Delete, Follow, Move, Object as Object$1, PUBLIC_COLLECTION, Reject, Service, Undo, Update, isActor } from "@fedify/fedify/vocab";
2
+ import { Accept, Create, Delete, Follow, Move, Object as Object$1, Reject, Service, Undo, Update, isActor } from "@fedify/fedify/vocab";
3
3
 
4
4
  //#region src/relay.ts
5
5
  const RELAY_SERVER_ACTOR = "relay";
@@ -187,199 +187,7 @@ var LitePubRelay = class {
187
187
  #subscriptionHandler;
188
188
  constructor(options) {
189
189
  this.#options = options;
190
- this.#federation = options.federation ?? createFederation({
191
- kv: options.kv,
192
- queue: options.queue,
193
- documentLoaderFactory: options.documentLoaderFactory,
194
- authenticatedDocumentLoaderFactory: options.authenticatedDocumentLoaderFactory
195
- });
196
- this.#federation.setActorDispatcher("/users/{identifier}", async (ctx, identifier) => {
197
- if (identifier !== RELAY_SERVER_ACTOR) return null;
198
- const keys = await ctx.getActorKeyPairs(identifier);
199
- return new Application({
200
- id: ctx.getActorUri(identifier),
201
- preferredUsername: identifier,
202
- name: "ActivityPub Relay",
203
- summary: "LitePub-compatible ActivityPub relay server",
204
- inbox: ctx.getInboxUri(),
205
- followers: ctx.getFollowersUri(identifier),
206
- url: ctx.getActorUri(identifier),
207
- publicKey: keys[0].cryptographicKey,
208
- assertionMethods: keys.map((k) => k.multikey)
209
- });
210
- }).setKeyPairsDispatcher(async (_ctx, identifier) => {
211
- if (identifier !== RELAY_SERVER_ACTOR) return [];
212
- const rsaPairJson = await options.kv.get([
213
- "keypair",
214
- "rsa",
215
- identifier
216
- ]);
217
- const ed25519PairJson = await options.kv.get([
218
- "keypair",
219
- "ed25519",
220
- identifier
221
- ]);
222
- if (rsaPairJson == null || ed25519PairJson == null) {
223
- const rsaPair$1 = await generateCryptoKeyPair("RSASSA-PKCS1-v1_5");
224
- const ed25519Pair$1 = await generateCryptoKeyPair("Ed25519");
225
- await options.kv.set([
226
- "keypair",
227
- "rsa",
228
- identifier
229
- ], {
230
- privateKey: await exportJwk(rsaPair$1.privateKey),
231
- publicKey: await exportJwk(rsaPair$1.publicKey)
232
- });
233
- await options.kv.set([
234
- "keypair",
235
- "ed25519",
236
- identifier
237
- ], {
238
- privateKey: await exportJwk(ed25519Pair$1.privateKey),
239
- publicKey: await exportJwk(ed25519Pair$1.publicKey)
240
- });
241
- return [rsaPair$1, ed25519Pair$1];
242
- }
243
- const rsaPair = {
244
- privateKey: await importJwk(rsaPairJson.privateKey, "private"),
245
- publicKey: await importJwk(rsaPairJson.publicKey, "public")
246
- };
247
- const ed25519Pair = {
248
- privateKey: await importJwk(ed25519PairJson.privateKey, "private"),
249
- publicKey: await importJwk(ed25519PairJson.publicKey, "public")
250
- };
251
- return [rsaPair, ed25519Pair];
252
- });
253
- this.#federation.setFollowersDispatcher("/users/{identifier}/followers", async (_ctx, identifier) => {
254
- if (identifier !== RELAY_SERVER_ACTOR) return null;
255
- const followers = await options.kv.get(["followers"]) ?? [];
256
- const actors = [];
257
- for (const followerId of followers) {
258
- const follower = await options.kv.get(["follower", followerId]);
259
- if (!follower) continue;
260
- const actor = await Object$1.fromJsonLd(follower.actor);
261
- if (!isActor(actor)) continue;
262
- actors.push(actor);
263
- }
264
- return { items: actors };
265
- });
266
- this.#federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(Follow, async (ctx, follow) => {
267
- if (follow.id == null || follow.objectId == null) return;
268
- const parsed = ctx.parseUri(follow.objectId);
269
- const isPublicFollow = follow.objectId.href === "https://www.w3.org/ns/activitystreams#Public";
270
- if (!isPublicFollow && parsed?.type !== "actor") return;
271
- 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]);
275
- if (existingFollow?.state === "pending") return;
276
- let subscriptionApproved = false;
277
- if (this.#subscriptionHandler) subscriptionApproved = await this.#subscriptionHandler(ctx, recipient);
278
- if (subscriptionApproved) {
279
- await options.kv.set(["follower", recipient.id.href], {
280
- "actor": await recipient.toJsonLd(),
281
- "state": "pending"
282
- });
283
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new Accept({
284
- id: new URL(`#accepts`, relayActorUri),
285
- actor: relayActorUri,
286
- object: follow
287
- }));
288
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new Follow({
289
- actor: relayActorUri,
290
- object: recipient.id,
291
- to: recipient.id
292
- }));
293
- } else await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, recipient, new Reject({
294
- id: new URL(`#rejects`, relayActorUri),
295
- actor: relayActorUri,
296
- object: follow
297
- }));
298
- }).on(Accept, async (ctx, accept) => {
299
- const follow = await accept.getObject();
300
- if (!(follow instanceof Follow)) return;
301
- const following = await accept.getActor();
302
- if (!isActor(following)) return;
303
- const follower = follow.actorId;
304
- if (follower == null) return;
305
- const parsed = ctx.parseUri(follower);
306
- if (parsed == null || parsed.type !== "actor") return;
307
- const followerData = await options.kv.get(["follower", follower.href]);
308
- if (followerData == null) return;
309
- const updatedFollowerData = {
310
- ...followerData,
311
- status: "accepted"
312
- };
313
- await options.kv.set(["follower", follower.href], updatedFollowerData);
314
- const followers = await options.kv.get(["followers"]) ?? [];
315
- followers.push(follower.href);
316
- await options.kv.set(["followers"], followers);
317
- }).on(Undo, async (ctx, undo) => {
318
- const activity = await undo.getObject(ctx);
319
- if (activity instanceof Follow) {
320
- if (activity.id == null || activity.actorId == null) return;
321
- const followers = await options.kv.get(["followers"]) ?? [];
322
- const updatedFollowers = followers.filter((id) => id !== activity.actorId?.href);
323
- await options.kv.set(["followers"], updatedFollowers);
324
- options.kv.delete(["follower", activity.actorId?.href]);
325
- } else console.warn("Unsupported object type ({type}) for Undo activity: {object}", {
326
- type: activity?.constructor.name,
327
- object: activity
328
- });
329
- }).on(Create, async (ctx, create) => {
330
- const sender = await create.getActor(ctx);
331
- const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
332
- const announce = new Announce({
333
- id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
334
- actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
335
- object: create.objectId,
336
- to: PUBLIC_COLLECTION,
337
- published: Temporal.Now.instant()
338
- });
339
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
340
- excludeBaseUris,
341
- preferSharedInbox: true
342
- });
343
- }).on(Update, async (ctx, update) => {
344
- const sender = await update.getActor(ctx);
345
- const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
346
- const announce = new Announce({
347
- id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
348
- actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
349
- object: update.objectId,
350
- to: PUBLIC_COLLECTION
351
- });
352
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
353
- excludeBaseUris,
354
- preferSharedInbox: true
355
- });
356
- }).on(Move, async (ctx, move) => {
357
- const sender = await move.getActor(ctx);
358
- const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
359
- const announce = new Announce({
360
- id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
361
- actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
362
- object: move.objectId,
363
- to: PUBLIC_COLLECTION
364
- });
365
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
366
- excludeBaseUris,
367
- preferSharedInbox: true
368
- });
369
- }).on(Delete, async (ctx, deleteActivity) => {
370
- const sender = await deleteActivity.getActor(ctx);
371
- const excludeBaseUris = sender?.id ? [new URL(sender.id)] : [];
372
- const announce = new Announce({
373
- id: new URL(`/announce#${crypto.randomUUID()}`, ctx.origin),
374
- actor: ctx.getActorUri(RELAY_SERVER_ACTOR),
375
- object: deleteActivity.objectId,
376
- to: PUBLIC_COLLECTION
377
- });
378
- await ctx.sendActivity({ identifier: RELAY_SERVER_ACTOR }, "followers", announce, {
379
- excludeBaseUris,
380
- preferSharedInbox: true
381
- });
382
- });
190
+ this.#federation = createFederation({ kv: options.kv });
383
191
  }
384
192
  get domain() {
385
193
  return this.#options.domain || "localhost";
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.478.1916+5db44d85",
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.478.1916+5db44d85"
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.478.1916+5db44d85",
57
+ "@fedify/vocab-runtime": "^2.0.0-pr.478.1916+5db44d85"
58
58
  },
59
59
  "scripts": {
60
60
  "build": "deno task codegen && tsdown",