feat: federation hardening — persistent keys, Redis queue, indexes

- Persist Ed25519 key pair to ap_keys collection via exportJwk/importJwk
  instead of regenerating on every request (fixes OIP verification failures)
- Use assertionMethods (plural array) per Fedify spec
- Add @fedify/redis + ioredis for persistent message queue that survives
  process restarts (falls back to InProcessMessageQueue when no Redis)
- Add Reject inbox listener to mark rejected Follow requests
- Add performance indexes on ap_followers, ap_following, ap_activities
- Wire storeRawActivities flag through to activity logging
- Bump version to 1.0.21
This commit is contained in:
Ricardo
2026-02-20 16:33:13 +01:00
parent 5604771c69
commit be369b1677
6 changed files with 1537 additions and 24 deletions

View File

@@ -41,6 +41,7 @@ const defaults = {
alsoKnownAs: "",
activityRetentionDays: 90,
storeRawActivities: false,
redisUrl: "",
};
export default class ActivityPubEndpoint {
@@ -617,6 +618,28 @@ export default class ActivityPubEndpoint {
);
}
// Performance indexes for inbox handlers and batch refollow
this._collections.ap_followers.createIndex(
{ actorUrl: 1 },
{ unique: true, background: true },
);
this._collections.ap_following.createIndex(
{ actorUrl: 1 },
{ unique: true, background: true },
);
this._collections.ap_following.createIndex(
{ source: 1 },
{ background: true },
);
this._collections.ap_activities.createIndex(
{ objectUrl: 1 },
{ background: true },
);
this._collections.ap_activities.createIndex(
{ type: 1, actorUrl: 1, objectUrl: 1 },
{ background: true },
);
// Seed actor profile from config on first run
this._seedProfile().catch((error) => {
console.warn("[ActivityPub] Profile seed failed:", error.message);
@@ -628,6 +651,7 @@ export default class ActivityPubEndpoint {
mountPath: this.options.mountPath,
handle: this.options.actor.handle,
storeRawActivities: this.options.storeRawActivities,
redisUrl: this.options.redisUrl,
});
this._federation = federation;