mirror of
https://github.com/svemagie/indiekit-endpoint-activitypub.git
synced 2026-04-02 15:44:58 +02:00
Merge upstream rmdes:main — v2.13.0–v2.15.4 into svemagie/main
New upstream features:
- v2.13.0: FEP-8fcf/fe34 compliance, custom emoji, manual follow approval
- v2.14.0: Server blocking, Redis caching, key refresh, async inbox queue
- v2.15.0: Outbox failure handling (strike system), reply chain forwarding
- v2.15.1: Reply intelligence in reader (visibility badges, thread reconstruction)
- v2.15.2: Strip invalid as:Endpoints type from actor serialization
- v2.15.3: Exclude soft-deleted posts from outbox/content negotiation
- v2.15.4: Wire content-warning property for CW text
Conflict resolution:
- federation-setup.js: merged our draft/unlisted/visibility filters with
upstream's soft-delete filter
- compose.js: kept our DM compose path, adopted upstream's
lookupWithSecurity for remote object resolution
- notifications.js: kept our separate reply/mention tabs, added upstream's
follow_request grouping
- inbox-listeners.js: took upstream's thin-shim rewrite (handlers moved to
inbox-handlers.js which already has DM detection)
- notification-card.njk: merged DM badge with follow_request support
Preserved from our fork:
- Like/Announce to:Public cc:followers addressing
- Nested tag normalization (cat.split("/").at(-1))
- DM compose/reply path in compose controller
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
64
README.md
64
README.md
@@ -43,6 +43,28 @@ Private ActivityPub messages (messages addressed only to your actor, with no `as
|
||||
- Reply delivery — replies are addressed to and delivered directly to the original post's author
|
||||
- Shared inbox support with collection sync (FEP-8fcf)
|
||||
- Configurable actor type (Person, Service, Organization, Group)
|
||||
- Manual follow approval — review and accept/reject follow requests before they take effect
|
||||
- Direct messages — private conversations stored separately from the public timeline
|
||||
|
||||
**Federation Resilience** *(v2.14.0+)*
|
||||
- Async inbox queue — inbound activities are persisted to MongoDB before processing, ensuring no data loss on crashes
|
||||
- Server blocking — block entire remote servers by domain, rejecting all inbound activities from blocked instances
|
||||
- Key freshness tracking — tracks when remote actor keys were last verified, skipping redundant re-fetches
|
||||
- Redis-cached actor lookups — caches actor resolution results to reduce network round-trips
|
||||
- Delivery strike tracking on `ap_followers` — counts consecutive delivery failures per follower
|
||||
- FEP-fe34 security — verifies `proof.created` timestamps to reject replayed activities
|
||||
|
||||
**Outbox Failure Handling** *(v2.15.0+, inspired by [Hollo](https://github.com/fedify-dev/hollo))*
|
||||
- **410 Gone** — immediate full cleanup: removes the follower, their timeline items, and their notifications
|
||||
- **404 Not Found** — strike system: 3 consecutive failures over 7+ days triggers the same full cleanup
|
||||
- Strike auto-reset — when an actor sends us any activity, their delivery failure count resets to zero
|
||||
- Prevents orphaned data from accumulating over time while tolerating temporary server outages
|
||||
|
||||
**Reply Intelligence** *(v2.15.0+, inspired by [Hollo](https://github.com/fedify-dev/hollo))*
|
||||
- Recursive reply chain fetching — when a reply arrives, fetches parent posts up to 5 levels deep for thread context
|
||||
- Ancestor posts stored with `isContext: true` flag for thread view without cluttering the main timeline
|
||||
- Reply forwarding to followers — when someone replies to our posts, the reply is forwarded to our followers so they see the full conversation
|
||||
- Write-time visibility classification — computes `public`/`unlisted`/`private`/`direct` from `to`/`cc` fields at ingest time
|
||||
|
||||
**Reader**
|
||||
- Timeline view showing posts from followed accounts with tab filtering (notes, articles, replies, boosts, media)
|
||||
@@ -67,6 +89,8 @@ Private ActivityPub messages (messages addressed only to your actor, with no `as
|
||||
**Moderation**
|
||||
- Mute actors or keywords
|
||||
- Block actors (also removes from followers)
|
||||
- Block entire servers by domain
|
||||
- Report remote actors to their home instance (Flag activity)
|
||||
- All moderation actions available from the reader UI
|
||||
|
||||
**Mastodon Migration**
|
||||
@@ -229,6 +253,7 @@ When remote servers send activities to your inbox:
|
||||
- **Accept(Follow)** → Marks our follow as accepted
|
||||
- **Reject(Follow)** → Marks our follow as rejected
|
||||
- **Block** → Removes actor from our followers
|
||||
- **Flag** → Outbound report sent to remote actor's instance
|
||||
|
||||
### Direct Message Detection
|
||||
|
||||
@@ -307,7 +332,7 @@ The plugin creates these collections automatically:
|
||||
|
||||
| Collection | Description |
|
||||
|---|---|
|
||||
| `ap_followers` | Accounts following your actor |
|
||||
| `ap_followers` | Accounts following your actor (includes delivery failure strike tracking) |
|
||||
| `ap_following` | Accounts you follow |
|
||||
| `ap_activities` | Activity log with automatic TTL cleanup |
|
||||
| `ap_keys` | RSA and Ed25519 key pairs for HTTP Signatures |
|
||||
@@ -315,11 +340,19 @@ The plugin creates these collections automatically:
|
||||
| `ap_profile` | Actor profile (single document) |
|
||||
| `ap_featured` | Pinned/featured posts |
|
||||
| `ap_featured_tags` | Featured hashtags |
|
||||
| `ap_timeline` | Reader timeline items from followed accounts |
|
||||
| `ap_timeline` | Reader timeline items (includes `visibility`, `isContext`, `isDirect` fields) |
|
||||
| `ap_notifications` | Interaction notifications (includes `isDirect` and `senderActorUrl` fields for DMs) |
|
||||
| `ap_muted` | Muted actors and keywords |
|
||||
| `ap_blocked` | Blocked actors |
|
||||
| `ap_interactions` | Per-post like/boost tracking |
|
||||
| `ap_messages` | Direct messages / private conversations |
|
||||
| `ap_followed_tags` | Hashtags you follow for timeline filtering |
|
||||
| `ap_explore_tabs` | Saved Mastodon instances for the explore view |
|
||||
| `ap_reports` | Outbound reports (Flag activities) sent to remote instances |
|
||||
| `ap_pending_follows` | Follow requests awaiting manual approval |
|
||||
| `ap_blocked_servers` | Blocked server domains (instance-level blocks) |
|
||||
| `ap_key_freshness` | Tracks when remote actor keys were last verified |
|
||||
| `ap_inbox_queue` | Persistent async inbox processing queue |
|
||||
|
||||
## Supported Post Types
|
||||
|
||||
@@ -361,6 +394,23 @@ Mastodon's `update_account_fields` checks `attachment.is_a?(Array)` and silently
|
||||
|
||||
**Revisit when:** Fedify adds an option to preserve arrays during JSON-LD serialization, or Mastodon fixes their array check.
|
||||
|
||||
### Endpoints `as:Endpoints` Type Stripping
|
||||
|
||||
**File:** `lib/federation-bridge.js` (in `sendFedifyResponse()`)
|
||||
**Upstream issue:** [fedify#576](https://github.com/fedify-dev/fedify/issues/576) — FIXED in Fedify 2.1.0
|
||||
|
||||
Fedify serializes the `endpoints` object with `"type": "as:Endpoints"`, which is not a valid ActivityStreams type. browser.pub rejects this. The bridge strips the `type` field from the `endpoints` object before sending.
|
||||
|
||||
**Remove when:** Upgrading to Fedify ≥ 2.1.0.
|
||||
|
||||
### PropertyValue Attachment Type (Known Issue)
|
||||
|
||||
**Upstream issue:** [fedify#629](https://github.com/fedify-dev/fedify/issues/629) — OPEN
|
||||
|
||||
Fedify serializes `PropertyValue` attachments (used by Mastodon for profile metadata fields) with `"type": "PropertyValue"`, a schema.org type that is not a valid AS2 Object or Link. browser.pub rejects `/attachment` as invalid. However, every Mastodon-compatible server emits `PropertyValue` — removing it would break profile field display across the fediverse.
|
||||
|
||||
**No workaround applied.** This is a de facto fediverse standard despite not being in the AS2 vocabulary.
|
||||
|
||||
### `.authorize()` Not Chained on Actor Dispatcher
|
||||
|
||||
**File:** `lib/federation-setup.js` (line ~254)
|
||||
@@ -403,6 +453,16 @@ This is not a bug — Fedify requires explicit opt-in for signed fetches. But it
|
||||
- **Existing DMs before this fork** — Notifications received before upgrading to this fork lack `isDirect`/`senderActorUrl` and won't appear in the Direct tab (resend or patch manually in MongoDB)
|
||||
- **No read receipts** — Outbound DMs are stored locally but the recipient receives no read-receipt activity
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
This plugin builds on the excellent [Fedify](https://fedify.dev) framework by [Hong Minhee](https://github.com/dahlia). Fedify provides the core ActivityPub federation layer — HTTP Signatures, content negotiation, message queues, and the vocabulary types that make all of this possible.
|
||||
|
||||
Several federation patterns in this plugin were inspired by studying other open-source ActivityPub implementations:
|
||||
|
||||
- **[Hollo](https://github.com/fedify-dev/hollo)** (by the Fedify author) — A single-user Fedify-based ActivityPub server that served as the primary reference implementation. The outbox permanent failure handling (410 cleanup and 404 strike system), recursive reply chain fetching, reply forwarding to followers, and write-time visibility classification in v2.15.0 are all adapted from Hollo's patterns for a MongoDB/single-user context.
|
||||
|
||||
- **[Wafrn](https://github.com/gabboman/wafrn)** — A federated social network whose ActivityPub implementation informed the operational resilience patterns added in v2.14.0. Server blocking, key freshness tracking, async inbox processing with persistent queues, and the general approach to federation hardening were inspired by studying Wafrn's production codebase.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
Reference in New Issue
Block a user