@fedify/fedify 1.0.0-dev.402 → 1.0.0-dev.404
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/CHANGES.md +66 -0
- package/esm/federation/handler.js +27 -27
- package/esm/federation/middleware.js +347 -134
- package/esm/webfinger/handler.js +12 -12
- package/package.json +1 -1
- package/types/federation/callback.d.ts +32 -15
- package/types/federation/callback.d.ts.map +1 -1
- package/types/federation/context.d.ts +96 -57
- package/types/federation/context.d.ts.map +1 -1
- package/types/federation/federation.d.ts +33 -34
- package/types/federation/federation.d.ts.map +1 -1
- package/types/federation/handler.d.ts +6 -6
- package/types/federation/handler.d.ts.map +1 -1
- package/types/federation/middleware.d.ts +39 -23
- package/types/federation/middleware.d.ts.map +1 -1
- package/types/federation/queue.d.ts +1 -1
- package/types/federation/queue.d.ts.map +1 -1
- package/types/webfinger/handler.d.ts +1 -1
@@ -197,10 +197,10 @@ export class FederationImpl {
|
|
197
197
|
const logger = getLogger(["fedify", "federation", "inbox"]);
|
198
198
|
const baseUrl = new URL(message.baseUrl);
|
199
199
|
let context = this.#createContext(baseUrl, ctxData);
|
200
|
-
if (message.
|
200
|
+
if (message.identifier != null) {
|
201
201
|
context = this.#createContext(baseUrl, ctxData, {
|
202
202
|
documentLoader: await context.getDocumentLoader({
|
203
|
-
|
203
|
+
identifier: message.identifier,
|
204
204
|
}),
|
205
205
|
});
|
206
206
|
}
|
@@ -208,7 +208,8 @@ export class FederationImpl {
|
|
208
208
|
const identity = await this.sharedInboxKeyDispatcher(context);
|
209
209
|
if (identity != null) {
|
210
210
|
context = this.#createContext(baseUrl, ctxData, {
|
211
|
-
documentLoader: "
|
211
|
+
documentLoader: "identifier" in identity || "username" in identity ||
|
212
|
+
"handle" in identity
|
212
213
|
? await context.getDocumentLoader(identity)
|
213
214
|
: context.getDocumentLoader(identity),
|
214
215
|
});
|
@@ -332,36 +333,41 @@ export class FederationImpl {
|
|
332
333
|
throw new RouterError("Actor dispatcher already set.");
|
333
334
|
}
|
334
335
|
const variables = this.router.add(path, "actor");
|
335
|
-
if (variables.size !== 1 ||
|
336
|
-
|
336
|
+
if (variables.size !== 1 ||
|
337
|
+
!(variables.has("identifier") || variables.has("handle"))) {
|
338
|
+
throw new RouterError("Path for actor dispatcher must have one variable: {identifier}");
|
339
|
+
}
|
340
|
+
if (variables.has("handle")) {
|
341
|
+
getLogger(["fedify", "federation", "actor"]).warn("The {handle} variable in the actor dispatcher path is deprecated. " +
|
342
|
+
"Use {identifier} instead.");
|
337
343
|
}
|
338
344
|
const callbacks = {
|
339
|
-
dispatcher: async (context,
|
340
|
-
const actor = await dispatcher(context,
|
345
|
+
dispatcher: async (context, identifier) => {
|
346
|
+
const actor = await dispatcher(context, identifier);
|
341
347
|
if (actor == null)
|
342
348
|
return null;
|
343
349
|
const logger = getLogger(["fedify", "federation", "actor"]);
|
344
350
|
if (actor.id == null) {
|
345
351
|
logger.warn("Actor dispatcher returned an actor without an id property. " +
|
346
|
-
"Set the property with Context.getActorUri(
|
352
|
+
"Set the property with Context.getActorUri(identifier).");
|
347
353
|
}
|
348
|
-
else if (actor.id.href != context.getActorUri(
|
354
|
+
else if (actor.id.href != context.getActorUri(identifier).href) {
|
349
355
|
logger.warn("Actor dispatcher returned an actor with an id property that " +
|
350
356
|
"does not match the actor URI. Set the property with " +
|
351
|
-
"Context.getActorUri(
|
357
|
+
"Context.getActorUri(identifier).");
|
352
358
|
}
|
353
359
|
if (this.followingCallbacks != null &&
|
354
360
|
this.followingCallbacks.dispatcher != null) {
|
355
361
|
if (actor.followingId == null) {
|
356
362
|
logger.warn("You configured a following collection dispatcher, but the " +
|
357
363
|
"actor does not have a following property. Set the property " +
|
358
|
-
"with Context.getFollowingUri(
|
364
|
+
"with Context.getFollowingUri(identifier).");
|
359
365
|
}
|
360
|
-
else if (actor.followingId.href != context.getFollowingUri(
|
366
|
+
else if (actor.followingId.href != context.getFollowingUri(identifier).href) {
|
361
367
|
logger.warn("You configured a following collection dispatcher, but the " +
|
362
368
|
"actor's following property does not match the following " +
|
363
369
|
"collection URI. Set the property with " +
|
364
|
-
"Context.getFollowingUri(
|
370
|
+
"Context.getFollowingUri(identifier).");
|
365
371
|
}
|
366
372
|
}
|
367
373
|
if (this.followersCallbacks != null &&
|
@@ -369,13 +375,13 @@ export class FederationImpl {
|
|
369
375
|
if (actor.followersId == null) {
|
370
376
|
logger.warn("You configured a followers collection dispatcher, but the " +
|
371
377
|
"actor does not have a followers property. Set the property " +
|
372
|
-
"with Context.getFollowersUri(
|
378
|
+
"with Context.getFollowersUri(identifier).");
|
373
379
|
}
|
374
|
-
else if (actor.followersId.href != context.getFollowersUri(
|
380
|
+
else if (actor.followersId.href != context.getFollowersUri(identifier).href) {
|
375
381
|
logger.warn("You configured a followers collection dispatcher, but the " +
|
376
382
|
"actor's followers property does not match the followers " +
|
377
383
|
"collection URI. Set the property with " +
|
378
|
-
"Context.getFollowersUri(
|
384
|
+
"Context.getFollowersUri(identifier).");
|
379
385
|
}
|
380
386
|
}
|
381
387
|
if (this.outboxCallbacks != null &&
|
@@ -383,12 +389,12 @@ export class FederationImpl {
|
|
383
389
|
if (actor?.outboxId == null) {
|
384
390
|
logger.warn("You configured an outbox collection dispatcher, but the " +
|
385
391
|
"actor does not have an outbox property. Set the property " +
|
386
|
-
"with Context.getOutboxUri(
|
392
|
+
"with Context.getOutboxUri(identifier).");
|
387
393
|
}
|
388
|
-
else if (actor.outboxId.href != context.getOutboxUri(
|
394
|
+
else if (actor.outboxId.href != context.getOutboxUri(identifier).href) {
|
389
395
|
logger.warn("You configured an outbox collection dispatcher, but the " +
|
390
396
|
"actor's outbox property does not match the outbox collection " +
|
391
|
-
"URI. Set the property with Context.getOutboxUri(
|
397
|
+
"URI. Set the property with Context.getOutboxUri(identifier).");
|
392
398
|
}
|
393
399
|
}
|
394
400
|
if (this.likedCallbacks != null &&
|
@@ -396,12 +402,12 @@ export class FederationImpl {
|
|
396
402
|
if (actor?.likedId == null) {
|
397
403
|
logger.warn("You configured a liked collection dispatcher, but the " +
|
398
404
|
"actor does not have a liked property. Set the property " +
|
399
|
-
"with Context.getLikedUri(
|
405
|
+
"with Context.getLikedUri(identifier).");
|
400
406
|
}
|
401
|
-
else if (actor.likedId.href != context.getLikedUri(
|
407
|
+
else if (actor.likedId.href != context.getLikedUri(identifier).href) {
|
402
408
|
logger.warn("You configured a liked collection dispatcher, but the " +
|
403
409
|
"actor's liked property does not match the liked collection " +
|
404
|
-
"URI. Set the property with Context.getLikedUri(
|
410
|
+
"URI. Set the property with Context.getLikedUri(identifier).");
|
405
411
|
}
|
406
412
|
}
|
407
413
|
if (this.featuredCallbacks != null &&
|
@@ -409,12 +415,12 @@ export class FederationImpl {
|
|
409
415
|
if (actor?.featuredId == null) {
|
410
416
|
logger.warn("You configured a featured collection dispatcher, but the " +
|
411
417
|
"actor does not have a featured property. Set the property " +
|
412
|
-
"with Context.getFeaturedUri(
|
418
|
+
"with Context.getFeaturedUri(identifier).");
|
413
419
|
}
|
414
|
-
else if (actor.featuredId.href != context.getFeaturedUri(
|
420
|
+
else if (actor.featuredId.href != context.getFeaturedUri(identifier).href) {
|
415
421
|
logger.warn("You configured a featured collection dispatcher, but the " +
|
416
422
|
"actor's featured property does not match the featured collection " +
|
417
|
-
"URI. Set the property with Context.getFeaturedUri(
|
423
|
+
"URI. Set the property with Context.getFeaturedUri(identifier).");
|
418
424
|
}
|
419
425
|
}
|
420
426
|
if (this.featuredTagsCallbacks != null &&
|
@@ -422,25 +428,26 @@ export class FederationImpl {
|
|
422
428
|
if (actor?.featuredTagsId == null) {
|
423
429
|
logger.warn("You configured a featured tags collection dispatcher, but the " +
|
424
430
|
"actor does not have a featuredTags property. Set the property " +
|
425
|
-
"with Context.getFeaturedTagsUri(
|
431
|
+
"with Context.getFeaturedTagsUri(identifier).");
|
426
432
|
}
|
427
|
-
else if (actor.featuredTagsId.href !=
|
433
|
+
else if (actor.featuredTagsId.href !=
|
434
|
+
context.getFeaturedTagsUri(identifier).href) {
|
428
435
|
logger.warn("You configured a featured tags collection dispatcher, but the " +
|
429
436
|
"actor's featuredTags property does not match the featured tags " +
|
430
437
|
"collection URI. Set the property with " +
|
431
|
-
"Context.getFeaturedTagsUri(
|
438
|
+
"Context.getFeaturedTagsUri(identifier).");
|
432
439
|
}
|
433
440
|
}
|
434
441
|
if (this.router.has("inbox")) {
|
435
442
|
if (actor.inboxId == null) {
|
436
443
|
logger.warn("You configured inbox listeners, but the actor does not " +
|
437
444
|
"have an inbox property. Set the property with " +
|
438
|
-
"Context.getInboxUri(
|
445
|
+
"Context.getInboxUri(identifier).");
|
439
446
|
}
|
440
|
-
else if (actor.inboxId.href != context.getInboxUri(
|
447
|
+
else if (actor.inboxId.href != context.getInboxUri(identifier).href) {
|
441
448
|
logger.warn("You configured inbox listeners, but the actor's inbox " +
|
442
449
|
"property does not match the inbox URI. Set the property " +
|
443
|
-
"with Context.getInboxUri(
|
450
|
+
"with Context.getInboxUri(identifier).");
|
444
451
|
}
|
445
452
|
if (actor.endpoints == null || actor.endpoints.sharedInbox == null) {
|
446
453
|
logger.warn("You configured inbox listeners, but the actor does not have " +
|
@@ -457,12 +464,12 @@ export class FederationImpl {
|
|
457
464
|
if (actor.publicKeyId == null) {
|
458
465
|
logger.warn("You configured a key pairs dispatcher, but the actor does " +
|
459
466
|
"not have a publicKey property. Set the property with " +
|
460
|
-
"Context.getActorKeyPairs(
|
467
|
+
"Context.getActorKeyPairs(identifier).");
|
461
468
|
}
|
462
469
|
if (actor.assertionMethodId == null) {
|
463
470
|
logger.warn("You configured a key pairs dispatcher, but the actor does " +
|
464
471
|
"not have an assertionMethod property. Set the property " +
|
465
|
-
"with Context.getActorKeyPairs(
|
472
|
+
"with Context.getActorKeyPairs(identifier).");
|
466
473
|
}
|
467
474
|
}
|
468
475
|
return actor;
|
@@ -521,8 +528,13 @@ export class FederationImpl {
|
|
521
528
|
}
|
522
529
|
else {
|
523
530
|
const variables = this.router.add(path, "inbox");
|
524
|
-
if (variables.size !== 1 ||
|
525
|
-
|
531
|
+
if (variables.size !== 1 ||
|
532
|
+
!(variables.has("identifier") || variables.has("handle"))) {
|
533
|
+
throw new RouterError("Path for inbox dispatcher must have one variable: {identifier}");
|
534
|
+
}
|
535
|
+
if (variables.has("handle")) {
|
536
|
+
getLogger(["fedify", "federation", "inbox"]).warn("The {handle} variable in the inbox dispatcher path is deprecated. " +
|
537
|
+
"Use {identifier} instead.");
|
526
538
|
}
|
527
539
|
this.inboxPath = path;
|
528
540
|
}
|
@@ -553,8 +565,13 @@ export class FederationImpl {
|
|
553
565
|
throw new RouterError("Outbox dispatcher already set.");
|
554
566
|
}
|
555
567
|
const variables = this.router.add(path, "outbox");
|
556
|
-
if (variables.size !== 1 ||
|
557
|
-
|
568
|
+
if (variables.size !== 1 ||
|
569
|
+
!(variables.has("identifier") || variables.has("handle"))) {
|
570
|
+
throw new RouterError("Path for outbox dispatcher must have one variable: {identifier}");
|
571
|
+
}
|
572
|
+
if (variables.has("handle")) {
|
573
|
+
getLogger(["fedify", "federation", "outbox"]).warn("The {handle} variable in the outbox dispatcher path is deprecated. " +
|
574
|
+
"Use {identifier} instead.");
|
558
575
|
}
|
559
576
|
const callbacks = { dispatcher };
|
560
577
|
this.outboxCallbacks = callbacks;
|
@@ -583,8 +600,14 @@ export class FederationImpl {
|
|
583
600
|
throw new RouterError("Following collection dispatcher already set.");
|
584
601
|
}
|
585
602
|
const variables = this.router.add(path, "following");
|
586
|
-
if (variables.size !== 1 ||
|
587
|
-
|
603
|
+
if (variables.size !== 1 ||
|
604
|
+
!(variables.has("identifier") || variables.has("handle"))) {
|
605
|
+
throw new RouterError("Path for following collection dispatcher must have one variable: " +
|
606
|
+
"{identifier}");
|
607
|
+
}
|
608
|
+
if (variables.has("handle")) {
|
609
|
+
getLogger(["fedify", "federation", "collection"]).warn("The {handle} variable in the following collection dispatcher path " +
|
610
|
+
"is deprecated. Use {identifier} instead.");
|
588
611
|
}
|
589
612
|
const callbacks = { dispatcher };
|
590
613
|
this.followingCallbacks = callbacks;
|
@@ -613,8 +636,14 @@ export class FederationImpl {
|
|
613
636
|
throw new RouterError("Followers collection dispatcher already set.");
|
614
637
|
}
|
615
638
|
const variables = this.router.add(path, "followers");
|
616
|
-
if (variables.size !== 1 ||
|
617
|
-
|
639
|
+
if (variables.size !== 1 ||
|
640
|
+
!(variables.has("identifier") || variables.has("handle"))) {
|
641
|
+
throw new RouterError("Path for followers collection dispatcher must have one variable: " +
|
642
|
+
"{identifier}");
|
643
|
+
}
|
644
|
+
if (variables.has("handle")) {
|
645
|
+
getLogger(["fedify", "federation", "collection"]).warn("The {handle} variable in the followers collection dispatcher path " +
|
646
|
+
"is deprecated. Use {identifier} instead.");
|
618
647
|
}
|
619
648
|
const callbacks = { dispatcher };
|
620
649
|
this.followersCallbacks = callbacks;
|
@@ -643,8 +672,14 @@ export class FederationImpl {
|
|
643
672
|
throw new RouterError("Liked collection dispatcher already set.");
|
644
673
|
}
|
645
674
|
const variables = this.router.add(path, "liked");
|
646
|
-
if (variables.size !== 1 ||
|
647
|
-
|
675
|
+
if (variables.size !== 1 ||
|
676
|
+
!(variables.has("identifier") || variables.has("handle"))) {
|
677
|
+
throw new RouterError("Path for liked collection dispatcher must have one variable: " +
|
678
|
+
"{identifier}");
|
679
|
+
}
|
680
|
+
if (variables.has("handle")) {
|
681
|
+
getLogger(["fedify", "federation", "collection"]).warn("The {handle} variable in the liked collection dispatcher path " +
|
682
|
+
"is deprecated. Use {identifier} instead.");
|
648
683
|
}
|
649
684
|
const callbacks = { dispatcher };
|
650
685
|
this.likedCallbacks = callbacks;
|
@@ -673,8 +708,14 @@ export class FederationImpl {
|
|
673
708
|
throw new RouterError("Featured collection dispatcher already set.");
|
674
709
|
}
|
675
710
|
const variables = this.router.add(path, "featured");
|
676
|
-
if (variables.size !== 1 ||
|
677
|
-
|
711
|
+
if (variables.size !== 1 ||
|
712
|
+
!(variables.has("identifier") || variables.has("handle"))) {
|
713
|
+
throw new RouterError("Path for featured collection dispatcher must have one variable: " +
|
714
|
+
"{identifier}");
|
715
|
+
}
|
716
|
+
if (variables.has("handle")) {
|
717
|
+
getLogger(["fedify", "federation", "collection"]).warn("The {handle} variable in the featured collection dispatcher path " +
|
718
|
+
"is deprecated. Use {identifier} instead.");
|
678
719
|
}
|
679
720
|
const callbacks = { dispatcher };
|
680
721
|
this.featuredCallbacks = callbacks;
|
@@ -703,9 +744,14 @@ export class FederationImpl {
|
|
703
744
|
throw new RouterError("Featured tags collection dispatcher already set.");
|
704
745
|
}
|
705
746
|
const variables = this.router.add(path, "featuredTags");
|
706
|
-
if (variables.size !== 1 ||
|
747
|
+
if (variables.size !== 1 ||
|
748
|
+
!(variables.has("identifier") || variables.has("handle"))) {
|
707
749
|
throw new RouterError("Path for featured tags collection dispatcher must have one " +
|
708
|
-
"variable: {
|
750
|
+
"variable: {identifier}");
|
751
|
+
}
|
752
|
+
if (variables.has("handle")) {
|
753
|
+
getLogger(["fedify", "federation", "collection"]).warn("The {handle} variable in the featured tags collection dispatcher " +
|
754
|
+
"path is deprecated. Use {identifier} instead.");
|
709
755
|
}
|
710
756
|
const callbacks = { dispatcher };
|
711
757
|
this.featuredTagsCallbacks = callbacks;
|
@@ -740,10 +786,15 @@ export class FederationImpl {
|
|
740
786
|
}
|
741
787
|
else {
|
742
788
|
const variables = this.router.add(inboxPath, "inbox");
|
743
|
-
if (variables.size !== 1 ||
|
744
|
-
|
789
|
+
if (variables.size !== 1 ||
|
790
|
+
!(variables.has("identifier") || variables.has("handle"))) {
|
791
|
+
throw new RouterError("Path for inbox must have one variable: {identifier}");
|
745
792
|
}
|
746
793
|
this.inboxPath = inboxPath;
|
794
|
+
if (variables.has("handle")) {
|
795
|
+
getLogger(["fedify", "federation", "inbox"]).warn("The {handle} variable in the inbox path is deprecated. " +
|
796
|
+
"Use {identifier} instead.");
|
797
|
+
}
|
747
798
|
}
|
748
799
|
if (sharedInboxPath != null) {
|
749
800
|
const siVars = this.router.add(sharedInboxPath, "sharedInbox");
|
@@ -950,10 +1001,12 @@ export class FederationImpl {
|
|
950
1001
|
});
|
951
1002
|
case "actor":
|
952
1003
|
context = this.#createContext(request, contextData, {
|
953
|
-
invokedFromActorDispatcher: {
|
1004
|
+
invokedFromActorDispatcher: {
|
1005
|
+
identifier: route.values.identifier ?? route.values.handle,
|
1006
|
+
},
|
954
1007
|
});
|
955
1008
|
return await handleActor(request, {
|
956
|
-
|
1009
|
+
identifier: route.values.identifier ?? route.values.handle,
|
957
1010
|
context,
|
958
1011
|
actorDispatcher: this.actorCallbacks?.dispatcher,
|
959
1012
|
authorizePredicate: this.actorCallbacks?.authorizePredicate,
|
@@ -981,7 +1034,7 @@ export class FederationImpl {
|
|
981
1034
|
case "outbox":
|
982
1035
|
return await handleCollection(request, {
|
983
1036
|
name: "outbox",
|
984
|
-
|
1037
|
+
identifier: route.values.identifier ?? route.values.handle,
|
985
1038
|
uriGetter: context.getOutboxUri.bind(context),
|
986
1039
|
context,
|
987
1040
|
collectionCallbacks: this.outboxCallbacks,
|
@@ -993,7 +1046,7 @@ export class FederationImpl {
|
|
993
1046
|
if (request.method !== "POST") {
|
994
1047
|
return await handleCollection(request, {
|
995
1048
|
name: "inbox",
|
996
|
-
|
1049
|
+
identifier: route.values.identifier ?? route.values.handle,
|
997
1050
|
uriGetter: context.getInboxUri.bind(context),
|
998
1051
|
context,
|
999
1052
|
collectionCallbacks: this.inboxCallbacks,
|
@@ -1004,7 +1057,7 @@ export class FederationImpl {
|
|
1004
1057
|
}
|
1005
1058
|
context = this.#createContext(request, contextData, {
|
1006
1059
|
documentLoader: await context.getDocumentLoader({
|
1007
|
-
|
1060
|
+
identifier: route.values.identifier ?? route.values.handle,
|
1008
1061
|
}),
|
1009
1062
|
});
|
1010
1063
|
// falls through
|
@@ -1013,7 +1066,8 @@ export class FederationImpl {
|
|
1013
1066
|
const identity = await this.sharedInboxKeyDispatcher(context);
|
1014
1067
|
if (identity != null) {
|
1015
1068
|
context = this.#createContext(request, contextData, {
|
1016
|
-
documentLoader: "
|
1069
|
+
documentLoader: "identifier" in identity || "username" in identity ||
|
1070
|
+
"handle" in identity
|
1017
1071
|
? await context.getDocumentLoader(identity)
|
1018
1072
|
: context.getDocumentLoader(identity),
|
1019
1073
|
});
|
@@ -1022,7 +1076,7 @@ export class FederationImpl {
|
|
1022
1076
|
if (!this.manuallyStartQueue)
|
1023
1077
|
this.#startQueue(contextData);
|
1024
1078
|
return await handleInbox(request, {
|
1025
|
-
|
1079
|
+
identifier: route.values.identifier ?? route.values.handle ?? null,
|
1026
1080
|
context,
|
1027
1081
|
inboxContextFactory: context.toInboxContext.bind(context),
|
1028
1082
|
kv: this.kv,
|
@@ -1038,7 +1092,7 @@ export class FederationImpl {
|
|
1038
1092
|
case "following":
|
1039
1093
|
return await handleCollection(request, {
|
1040
1094
|
name: "following",
|
1041
|
-
|
1095
|
+
identifier: route.values.identifier ?? route.values.handle,
|
1042
1096
|
uriGetter: context.getFollowingUri.bind(context),
|
1043
1097
|
context,
|
1044
1098
|
collectionCallbacks: this.followingCallbacks,
|
@@ -1054,7 +1108,7 @@ export class FederationImpl {
|
|
1054
1108
|
}
|
1055
1109
|
return await handleCollection(request, {
|
1056
1110
|
name: "followers",
|
1057
|
-
|
1111
|
+
identifier: route.values.identifier ?? route.values.handle,
|
1058
1112
|
uriGetter: context.getFollowersUri.bind(context),
|
1059
1113
|
context,
|
1060
1114
|
filter: baseUrl != null ? new URL(baseUrl) : undefined,
|
@@ -1070,7 +1124,7 @@ export class FederationImpl {
|
|
1070
1124
|
case "liked":
|
1071
1125
|
return await handleCollection(request, {
|
1072
1126
|
name: "liked",
|
1073
|
-
|
1127
|
+
identifier: route.values.identifier ?? route.values.handle,
|
1074
1128
|
uriGetter: context.getLikedUri.bind(context),
|
1075
1129
|
context,
|
1076
1130
|
collectionCallbacks: this.likedCallbacks,
|
@@ -1081,7 +1135,7 @@ export class FederationImpl {
|
|
1081
1135
|
case "featured":
|
1082
1136
|
return await handleCollection(request, {
|
1083
1137
|
name: "featured",
|
1084
|
-
|
1138
|
+
identifier: route.values.identifier ?? route.values.handle,
|
1085
1139
|
uriGetter: context.getFeaturedUri.bind(context),
|
1086
1140
|
context,
|
1087
1141
|
collectionCallbacks: this.featuredCallbacks,
|
@@ -1092,7 +1146,7 @@ export class FederationImpl {
|
|
1092
1146
|
case "featuredTags":
|
1093
1147
|
return await handleCollection(request, {
|
1094
1148
|
name: "featured tags",
|
1095
|
-
|
1149
|
+
identifier: route.values.identifier ?? route.values.handle,
|
1096
1150
|
uriGetter: context.getFeaturedTagsUri.bind(context),
|
1097
1151
|
context,
|
1098
1152
|
collectionCallbacks: this.featuredTagsCallbacks,
|
@@ -1149,8 +1203,8 @@ class ContextImpl {
|
|
1149
1203
|
}
|
1150
1204
|
return new URL(path, this.url);
|
1151
1205
|
}
|
1152
|
-
getActorUri(
|
1153
|
-
const path = this.federation.router.build("actor", { handle });
|
1206
|
+
getActorUri(identifier) {
|
1207
|
+
const path = this.federation.router.build("actor", { identifier, handle: identifier });
|
1154
1208
|
if (path == null) {
|
1155
1209
|
throw new RouterError("No actor dispatcher registered.");
|
1156
1210
|
}
|
@@ -1174,57 +1228,57 @@ class ContextImpl {
|
|
1174
1228
|
}
|
1175
1229
|
return new URL(path, this.url);
|
1176
1230
|
}
|
1177
|
-
getOutboxUri(
|
1178
|
-
const path = this.federation.router.build("outbox", { handle });
|
1231
|
+
getOutboxUri(identifier) {
|
1232
|
+
const path = this.federation.router.build("outbox", { identifier, handle: identifier });
|
1179
1233
|
if (path == null) {
|
1180
1234
|
throw new RouterError("No outbox dispatcher registered.");
|
1181
1235
|
}
|
1182
1236
|
return new URL(path, this.url);
|
1183
1237
|
}
|
1184
|
-
getInboxUri(
|
1185
|
-
if (
|
1238
|
+
getInboxUri(identifier) {
|
1239
|
+
if (identifier == null) {
|
1186
1240
|
const path = this.federation.router.build("sharedInbox", {});
|
1187
1241
|
if (path == null) {
|
1188
1242
|
throw new RouterError("No shared inbox path registered.");
|
1189
1243
|
}
|
1190
1244
|
return new URL(path, this.url);
|
1191
1245
|
}
|
1192
|
-
const path = this.federation.router.build("inbox", { handle });
|
1246
|
+
const path = this.federation.router.build("inbox", { identifier, handle: identifier });
|
1193
1247
|
if (path == null) {
|
1194
1248
|
throw new RouterError("No inbox path registered.");
|
1195
1249
|
}
|
1196
1250
|
return new URL(path, this.url);
|
1197
1251
|
}
|
1198
|
-
getFollowingUri(
|
1199
|
-
const path = this.federation.router.build("following", { handle });
|
1252
|
+
getFollowingUri(identifier) {
|
1253
|
+
const path = this.federation.router.build("following", { identifier, handle: identifier });
|
1200
1254
|
if (path == null) {
|
1201
1255
|
throw new RouterError("No following collection path registered.");
|
1202
1256
|
}
|
1203
1257
|
return new URL(path, this.url);
|
1204
1258
|
}
|
1205
|
-
getFollowersUri(
|
1206
|
-
const path = this.federation.router.build("followers", { handle });
|
1259
|
+
getFollowersUri(identifier) {
|
1260
|
+
const path = this.federation.router.build("followers", { identifier, handle: identifier });
|
1207
1261
|
if (path == null) {
|
1208
1262
|
throw new RouterError("No followers collection path registered.");
|
1209
1263
|
}
|
1210
1264
|
return new URL(path, this.url);
|
1211
1265
|
}
|
1212
|
-
getLikedUri(
|
1213
|
-
const path = this.federation.router.build("liked", { handle });
|
1266
|
+
getLikedUri(identifier) {
|
1267
|
+
const path = this.federation.router.build("liked", { identifier, handle: identifier });
|
1214
1268
|
if (path == null) {
|
1215
1269
|
throw new RouterError("No liked collection path registered.");
|
1216
1270
|
}
|
1217
1271
|
return new URL(path, this.url);
|
1218
1272
|
}
|
1219
|
-
getFeaturedUri(
|
1220
|
-
const path = this.federation.router.build("featured", { handle });
|
1273
|
+
getFeaturedUri(identifier) {
|
1274
|
+
const path = this.federation.router.build("featured", { identifier, handle: identifier });
|
1221
1275
|
if (path == null) {
|
1222
1276
|
throw new RouterError("No featured collection path registered.");
|
1223
1277
|
}
|
1224
1278
|
return new URL(path, this.url);
|
1225
1279
|
}
|
1226
|
-
getFeaturedTagsUri(
|
1227
|
-
const path = this.federation.router.build("featuredTags", { handle });
|
1280
|
+
getFeaturedTagsUri(identifier) {
|
1281
|
+
const path = this.federation.router.build("featuredTags", { identifier, handle: identifier });
|
1228
1282
|
if (path == null) {
|
1229
1283
|
throw new RouterError("No featured tags collection path registered.");
|
1230
1284
|
}
|
@@ -1236,10 +1290,33 @@ class ContextImpl {
|
|
1236
1290
|
if (uri.origin !== this.url.origin)
|
1237
1291
|
return null;
|
1238
1292
|
const route = this.federation.router.route(uri.pathname);
|
1293
|
+
const logger = getLogger(["fedify", "federation"]);
|
1239
1294
|
if (route == null)
|
1240
1295
|
return null;
|
1241
|
-
else if (route.name === "
|
1242
|
-
return {
|
1296
|
+
else if (route.name === "sharedInbox") {
|
1297
|
+
return {
|
1298
|
+
type: "inbox",
|
1299
|
+
identifier: undefined,
|
1300
|
+
get handle() {
|
1301
|
+
logger.warn("The ParseUriResult.handle property is deprecated; " +
|
1302
|
+
"use ParseUriResult.identifier instead.");
|
1303
|
+
return undefined;
|
1304
|
+
},
|
1305
|
+
};
|
1306
|
+
}
|
1307
|
+
const identifier = "identifier" in route.values
|
1308
|
+
? route.values.identifier
|
1309
|
+
: route.values.handle;
|
1310
|
+
if (route.name === "actor") {
|
1311
|
+
return {
|
1312
|
+
type: "actor",
|
1313
|
+
identifier,
|
1314
|
+
get handle() {
|
1315
|
+
logger.warn("The ParseUriResult.handle property is deprecated; " +
|
1316
|
+
"use ParseUriResult.identifier instead.");
|
1317
|
+
return identifier;
|
1318
|
+
},
|
1319
|
+
};
|
1243
1320
|
}
|
1244
1321
|
else if (route.name.startsWith("object:")) {
|
1245
1322
|
const typeId = route.name.replace(/^object:/, "");
|
@@ -1251,50 +1328,104 @@ class ContextImpl {
|
|
1251
1328
|
};
|
1252
1329
|
}
|
1253
1330
|
else if (route.name === "inbox") {
|
1254
|
-
return {
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1331
|
+
return {
|
1332
|
+
type: "inbox",
|
1333
|
+
identifier,
|
1334
|
+
get handle() {
|
1335
|
+
logger.warn("The ParseUriResult.handle property is deprecated; " +
|
1336
|
+
"use ParseUriResult.identifier instead.");
|
1337
|
+
return identifier;
|
1338
|
+
},
|
1339
|
+
};
|
1258
1340
|
}
|
1259
1341
|
else if (route.name === "outbox") {
|
1260
|
-
return {
|
1342
|
+
return {
|
1343
|
+
type: "outbox",
|
1344
|
+
identifier,
|
1345
|
+
get handle() {
|
1346
|
+
logger.warn("The ParseUriResult.handle property is deprecated; " +
|
1347
|
+
"use ParseUriResult.identifier instead.");
|
1348
|
+
return identifier;
|
1349
|
+
},
|
1350
|
+
};
|
1261
1351
|
}
|
1262
1352
|
else if (route.name === "following") {
|
1263
|
-
return {
|
1353
|
+
return {
|
1354
|
+
type: "following",
|
1355
|
+
identifier,
|
1356
|
+
get handle() {
|
1357
|
+
logger.warn("The ParseUriResult.handle property is deprecated; " +
|
1358
|
+
"use ParseUriResult.identifier instead.");
|
1359
|
+
return identifier;
|
1360
|
+
},
|
1361
|
+
};
|
1264
1362
|
}
|
1265
1363
|
else if (route.name === "followers") {
|
1266
|
-
return {
|
1364
|
+
return {
|
1365
|
+
type: "followers",
|
1366
|
+
identifier,
|
1367
|
+
get handle() {
|
1368
|
+
logger.warn("The ParseUriResult.handle property is deprecated; " +
|
1369
|
+
"use ParseUriResult.identifier instead.");
|
1370
|
+
return identifier;
|
1371
|
+
},
|
1372
|
+
};
|
1267
1373
|
}
|
1268
1374
|
else if (route.name === "liked") {
|
1269
|
-
return {
|
1375
|
+
return {
|
1376
|
+
type: "liked",
|
1377
|
+
identifier,
|
1378
|
+
get handle() {
|
1379
|
+
logger.warn("The ParseUriResult.handle property is deprecated; " +
|
1380
|
+
"use ParseUriResult.identifier instead.");
|
1381
|
+
return identifier;
|
1382
|
+
},
|
1383
|
+
};
|
1270
1384
|
}
|
1271
1385
|
else if (route.name === "featured") {
|
1272
|
-
return {
|
1386
|
+
return {
|
1387
|
+
type: "featured",
|
1388
|
+
identifier,
|
1389
|
+
get handle() {
|
1390
|
+
logger.warn("The ParseUriResult.handle property is deprecated; " +
|
1391
|
+
"use ParseUriResult.identifier instead.");
|
1392
|
+
return identifier;
|
1393
|
+
},
|
1394
|
+
};
|
1273
1395
|
}
|
1274
1396
|
else if (route.name === "featuredTags") {
|
1275
|
-
return {
|
1397
|
+
return {
|
1398
|
+
type: "featuredTags",
|
1399
|
+
identifier,
|
1400
|
+
get handle() {
|
1401
|
+
logger.warn("The ParseUriResult.handle property is deprecated; " +
|
1402
|
+
"use ParseUriResult.identifier instead.");
|
1403
|
+
return identifier;
|
1404
|
+
},
|
1405
|
+
};
|
1276
1406
|
}
|
1277
1407
|
return null;
|
1278
1408
|
}
|
1279
|
-
async getActorKeyPairs(
|
1409
|
+
async getActorKeyPairs(identifier) {
|
1280
1410
|
const logger = getLogger(["fedify", "federation", "actor"]);
|
1281
1411
|
if (this.invokedFromActorKeyPairsDispatcher != null) {
|
1282
|
-
logger.warn("Context.getActorKeyPairs({
|
1412
|
+
logger.warn("Context.getActorKeyPairs({getActorKeyPairsIdentifier}) method is " +
|
1283
1413
|
"invoked from the actor key pairs dispatcher " +
|
1284
|
-
"({
|
1285
|
-
|
1286
|
-
|
1414
|
+
"({actorKeyPairsDispatcherIdentifier}); this may cause " +
|
1415
|
+
"an infinite loop.", {
|
1416
|
+
getActorKeyPairsIdentifier: identifier,
|
1417
|
+
actorKeyPairsDispatcherIdentifier: this.invokedFromActorKeyPairsDispatcher.identifier,
|
1287
1418
|
});
|
1288
1419
|
}
|
1289
1420
|
let keyPairs;
|
1290
1421
|
try {
|
1291
|
-
keyPairs = await this.
|
1422
|
+
keyPairs = await this.getKeyPairsFromIdentifier(identifier);
|
1292
1423
|
}
|
1293
1424
|
catch (_) {
|
1294
1425
|
logger.warn("No actor key pairs dispatcher registered.");
|
1295
1426
|
return [];
|
1296
1427
|
}
|
1297
|
-
const owner = this.getActorUri(
|
1428
|
+
const owner = this.getActorUri(identifier);
|
1298
1429
|
const result = [];
|
1299
1430
|
for (const keyPair of keyPairs) {
|
1300
1431
|
const newPair = {
|
@@ -1314,12 +1445,12 @@ class ContextImpl {
|
|
1314
1445
|
}
|
1315
1446
|
return result;
|
1316
1447
|
}
|
1317
|
-
async
|
1448
|
+
async getKeyPairsFromIdentifier(identifier) {
|
1318
1449
|
const logger = getLogger(["fedify", "federation", "actor"]);
|
1319
1450
|
if (this.federation.actorCallbacks?.keyPairsDispatcher == null) {
|
1320
1451
|
throw new Error("No actor key pairs dispatcher registered.");
|
1321
1452
|
}
|
1322
|
-
const path = this.federation.router.build("actor", { handle });
|
1453
|
+
const path = this.federation.router.build("actor", { identifier, handle: identifier });
|
1323
1454
|
if (path == null) {
|
1324
1455
|
logger.warn("No actor dispatcher registered.");
|
1325
1456
|
return [];
|
@@ -1327,10 +1458,10 @@ class ContextImpl {
|
|
1327
1458
|
const actorUri = new URL(path, this.url);
|
1328
1459
|
const keyPairs = await this.federation.actorCallbacks?.keyPairsDispatcher(new ContextImpl({
|
1329
1460
|
...this,
|
1330
|
-
invokedFromActorKeyPairsDispatcher: {
|
1331
|
-
}),
|
1461
|
+
invokedFromActorKeyPairsDispatcher: { identifier },
|
1462
|
+
}), identifier);
|
1332
1463
|
if (keyPairs.length < 1) {
|
1333
|
-
logger.warn("No key pairs found for actor {
|
1464
|
+
logger.warn("No key pairs found for actor {identifier}.", { identifier });
|
1334
1465
|
}
|
1335
1466
|
let i = 0;
|
1336
1467
|
const result = [];
|
@@ -1345,8 +1476,8 @@ class ContextImpl {
|
|
1345
1476
|
}
|
1346
1477
|
return result;
|
1347
1478
|
}
|
1348
|
-
async
|
1349
|
-
const keyPairs = await this.
|
1479
|
+
async getRsaKeyPairFromIdentifier(identifier) {
|
1480
|
+
const keyPairs = await this.getKeyPairsFromIdentifier(identifier);
|
1350
1481
|
for (const keyPair of keyPairs) {
|
1351
1482
|
const { privateKey } = keyPair;
|
1352
1483
|
if (privateKey.algorithm.name === "RSASSA-PKCS1-v1_5" &&
|
@@ -1356,15 +1487,44 @@ class ContextImpl {
|
|
1356
1487
|
return keyPair;
|
1357
1488
|
}
|
1358
1489
|
}
|
1359
|
-
getLogger(["fedify", "federation", "actor"]).warn("No RSA-PKCS#1-v1.5 SHA-256 key found for actor {
|
1490
|
+
getLogger(["fedify", "federation", "actor"]).warn("No RSA-PKCS#1-v1.5 SHA-256 key found for actor {identifier}.", { identifier });
|
1360
1491
|
return null;
|
1361
1492
|
}
|
1362
1493
|
getDocumentLoader(identity) {
|
1363
|
-
if ("handle" in identity) {
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1494
|
+
if ("identifier" in identity || "username" in identity || "handle" in identity) {
|
1495
|
+
let identifierPromise;
|
1496
|
+
if ("username" in identity || "handle" in identity) {
|
1497
|
+
let username;
|
1498
|
+
if ("username" in identity) {
|
1499
|
+
username = identity.username;
|
1500
|
+
}
|
1501
|
+
else {
|
1502
|
+
username = identity.handle;
|
1503
|
+
getLogger(["fedify", "runtime", "docloader"]).warn('The "handle" property is deprecated; use "identifier" or ' +
|
1504
|
+
'"username" instead.', { identity });
|
1505
|
+
}
|
1506
|
+
const mapper = this.federation.actorCallbacks?.handleMapper;
|
1507
|
+
if (mapper == null) {
|
1508
|
+
identifierPromise = Promise.resolve(username);
|
1509
|
+
}
|
1510
|
+
else {
|
1511
|
+
const identifier = mapper(this, username);
|
1512
|
+
identifierPromise = identifier instanceof Promise
|
1513
|
+
? identifier
|
1514
|
+
: Promise.resolve(identifier);
|
1515
|
+
}
|
1516
|
+
}
|
1517
|
+
else {
|
1518
|
+
identifierPromise = Promise.resolve(identity.identifier);
|
1519
|
+
}
|
1520
|
+
return identifierPromise.then((identifier) => {
|
1521
|
+
if (identifier == null)
|
1522
|
+
return this.documentLoader;
|
1523
|
+
const keyPair = this.getRsaKeyPairFromIdentifier(identifier);
|
1524
|
+
return keyPair.then((pair) => pair == null
|
1525
|
+
? this.documentLoader
|
1526
|
+
: this.federation.authenticatedDocumentLoaderFactory(pair));
|
1527
|
+
});
|
1368
1528
|
}
|
1369
1529
|
return this.federation.authenticatedDocumentLoaderFactory(identity);
|
1370
1530
|
}
|
@@ -1376,10 +1536,35 @@ class ContextImpl {
|
|
1376
1536
|
}
|
1377
1537
|
async sendActivity(sender, recipients, activity, options = {}) {
|
1378
1538
|
let keys;
|
1379
|
-
|
1380
|
-
|
1539
|
+
let identifier = null;
|
1540
|
+
if ("identifier" in sender || "username" in sender || "handle" in sender) {
|
1541
|
+
if ("identifier" in sender) {
|
1542
|
+
identifier = sender.identifier;
|
1543
|
+
}
|
1544
|
+
else {
|
1545
|
+
let username;
|
1546
|
+
if ("username" in sender) {
|
1547
|
+
username = sender.username;
|
1548
|
+
}
|
1549
|
+
else {
|
1550
|
+
username = sender.handle;
|
1551
|
+
getLogger(["fedify", "federation", "outbox"]).warn('The "handle" property for the sender parameter is deprecated; ' +
|
1552
|
+
'use "identifier" or "username" instead.', { sender });
|
1553
|
+
}
|
1554
|
+
if (this.federation.actorCallbacks?.handleMapper == null) {
|
1555
|
+
identifier = username;
|
1556
|
+
}
|
1557
|
+
else {
|
1558
|
+
const mapped = await this.federation.actorCallbacks.handleMapper(this, username);
|
1559
|
+
if (mapped == null) {
|
1560
|
+
throw new Error(`No actor found for the given username ${JSON.stringify(username)}.`);
|
1561
|
+
}
|
1562
|
+
identifier = mapped;
|
1563
|
+
}
|
1564
|
+
}
|
1565
|
+
keys = await this.getKeyPairsFromIdentifier(identifier);
|
1381
1566
|
if (keys.length < 1) {
|
1382
|
-
throw new Error(`No key pair found for actor ${JSON.stringify(
|
1567
|
+
throw new Error(`No key pair found for actor ${JSON.stringify(identifier)}.`);
|
1383
1568
|
}
|
1384
1569
|
}
|
1385
1570
|
else if (Array.isArray(sender)) {
|
@@ -1400,14 +1585,15 @@ class ContextImpl {
|
|
1400
1585
|
expandedRecipients = recipients;
|
1401
1586
|
}
|
1402
1587
|
else if (recipients === "followers") {
|
1403
|
-
if (
|
1404
|
-
throw new Error(
|
1588
|
+
if (identifier == null) {
|
1589
|
+
throw new Error('If recipients is "followers", ' +
|
1590
|
+
"sender must be an actor identifier or username.");
|
1405
1591
|
}
|
1406
1592
|
expandedRecipients = [];
|
1407
|
-
for await (const recipient of this.getFollowers(
|
1593
|
+
for await (const recipient of this.getFollowers(identifier)) {
|
1408
1594
|
expandedRecipients.push(recipient);
|
1409
1595
|
}
|
1410
|
-
const collectionId = this.federation.router.build("followers",
|
1596
|
+
const collectionId = this.federation.router.build("followers", { identifier, handle: identifier });
|
1411
1597
|
opts.collectionSync = collectionId == null
|
1412
1598
|
? undefined
|
1413
1599
|
: new URL(collectionId, this.url).href;
|
@@ -1417,11 +1603,11 @@ class ContextImpl {
|
|
1417
1603
|
}
|
1418
1604
|
return await this.federation.sendActivity(keys, expandedRecipients, activity, opts);
|
1419
1605
|
}
|
1420
|
-
async *getFollowers(
|
1606
|
+
async *getFollowers(identifier) {
|
1421
1607
|
if (this.federation.followersCallbacks == null) {
|
1422
1608
|
throw new Error("No followers collection dispatcher registered.");
|
1423
1609
|
}
|
1424
|
-
const result = await this.federation.followersCallbacks.dispatcher(this,
|
1610
|
+
const result = await this.federation.followersCallbacks.dispatcher(this, identifier, null);
|
1425
1611
|
if (result != null) {
|
1426
1612
|
for (const recipient of result.items)
|
1427
1613
|
yield recipient;
|
@@ -1430,9 +1616,9 @@ class ContextImpl {
|
|
1430
1616
|
if (this.federation.followersCallbacks.firstCursor == null) {
|
1431
1617
|
throw new Error("No first cursor dispatcher registered for followers collection.");
|
1432
1618
|
}
|
1433
|
-
let cursor = await this.federation.followersCallbacks.firstCursor(this,
|
1619
|
+
let cursor = await this.federation.followersCallbacks.firstCursor(this, identifier);
|
1434
1620
|
while (cursor != null) {
|
1435
|
-
const result = await this.federation.followersCallbacks.dispatcher(this,
|
1621
|
+
const result = await this.federation.followersCallbacks.dispatcher(this, identifier, cursor);
|
1436
1622
|
if (result == null)
|
1437
1623
|
break;
|
1438
1624
|
for (const recipient of result.items)
|
@@ -1453,23 +1639,23 @@ class RequestContextImpl extends ContextImpl {
|
|
1453
1639
|
this.request = options.request;
|
1454
1640
|
this.url = options.url;
|
1455
1641
|
}
|
1456
|
-
async getActor(
|
1642
|
+
async getActor(identifier) {
|
1457
1643
|
if (this.federation.actorCallbacks == null ||
|
1458
1644
|
this.federation.actorCallbacks.dispatcher == null) {
|
1459
1645
|
throw new Error("No actor dispatcher registered.");
|
1460
1646
|
}
|
1461
1647
|
if (this.#invokedFromActorDispatcher != null) {
|
1462
|
-
getLogger(["fedify", "federation", "actor"]).warn("RequestContext.getActor({
|
1463
|
-
"the actor dispatcher ({
|
1648
|
+
getLogger(["fedify", "federation", "actor"]).warn("RequestContext.getActor({getActorIdentifier}) is invoked from " +
|
1649
|
+
"the actor dispatcher ({actorDispatcherIdentifier}); " +
|
1464
1650
|
"this may cause an infinite loop.", {
|
1465
|
-
|
1466
|
-
|
1651
|
+
getActorIdentifier: identifier,
|
1652
|
+
actorDispatcherIdentifier: this.#invokedFromActorDispatcher.identifier,
|
1467
1653
|
});
|
1468
1654
|
}
|
1469
1655
|
return await this.federation.actorCallbacks.dispatcher(new RequestContextImpl({
|
1470
1656
|
...this,
|
1471
|
-
invokedFromActorDispatcher: {
|
1472
|
-
}),
|
1657
|
+
invokedFromActorDispatcher: { identifier },
|
1658
|
+
}), identifier);
|
1473
1659
|
}
|
1474
1660
|
async getObject(
|
1475
1661
|
// deno-lint-ignore no-explicit-any
|
@@ -1527,10 +1713,36 @@ export class InboxContextImpl extends ContextImpl {
|
|
1527
1713
|
async forwardActivity(forwarder, recipients, options) {
|
1528
1714
|
const logger = getLogger(["fedify", "federation", "inbox"]);
|
1529
1715
|
let keys;
|
1530
|
-
|
1531
|
-
|
1716
|
+
let identifier = null;
|
1717
|
+
if ("identifier" in forwarder || "username" in forwarder ||
|
1718
|
+
"handle" in forwarder) {
|
1719
|
+
if ("identifier" in forwarder) {
|
1720
|
+
identifier = forwarder.identifier;
|
1721
|
+
}
|
1722
|
+
else {
|
1723
|
+
let username;
|
1724
|
+
if ("username" in forwarder) {
|
1725
|
+
username = forwarder.username;
|
1726
|
+
}
|
1727
|
+
else {
|
1728
|
+
username = forwarder.handle;
|
1729
|
+
logger.warn('The "handle" property for the forwarder parameter is deprecated; ' +
|
1730
|
+
'use "identifier" or "username" instead.', { forwarder });
|
1731
|
+
}
|
1732
|
+
if (this.federation.actorCallbacks?.handleMapper == null) {
|
1733
|
+
identifier = username;
|
1734
|
+
}
|
1735
|
+
else {
|
1736
|
+
const mapped = await this.federation.actorCallbacks.handleMapper(this, username);
|
1737
|
+
if (mapped == null) {
|
1738
|
+
throw new Error(`No actor found for the given username ${JSON.stringify(username)}.`);
|
1739
|
+
}
|
1740
|
+
identifier = mapped;
|
1741
|
+
}
|
1742
|
+
}
|
1743
|
+
keys = await this.getKeyPairsFromIdentifier(identifier);
|
1532
1744
|
if (keys.length < 1) {
|
1533
|
-
throw new Error(`No key pair found for actor ${JSON.stringify(
|
1745
|
+
throw new Error(`No key pair found for actor ${JSON.stringify(identifier)}.`);
|
1534
1746
|
}
|
1535
1747
|
}
|
1536
1748
|
else if (Array.isArray(forwarder)) {
|
@@ -1571,11 +1783,12 @@ export class InboxContextImpl extends ContextImpl {
|
|
1571
1783
|
: undefined;
|
1572
1784
|
}
|
1573
1785
|
if (recipients === "followers") {
|
1574
|
-
if (
|
1575
|
-
throw new Error(
|
1786
|
+
if (identifier == null) {
|
1787
|
+
throw new Error('If recipients is "followers", ' +
|
1788
|
+
"forwarder must be an actor identifier or username.");
|
1576
1789
|
}
|
1577
1790
|
const followers = [];
|
1578
|
-
for await (const recipient of this.getFollowers(
|
1791
|
+
for await (const recipient of this.getFollowers(identifier)) {
|
1579
1792
|
followers.push(recipient);
|
1580
1793
|
}
|
1581
1794
|
recipients = followers;
|