From 80ef9bca1119389e63b20388769510de252ea5fb Mon Sep 17 00:00:00 2001 From: Ricardo Date: Wed, 25 Mar 2026 12:35:10 +0100 Subject: [PATCH] docs: update CLAUDE.md and README.md for v3.9 audit refactoring CLAUDE.md: - Architecture tree: add 4 extracted modules (batch-broadcast, syndicator, init-indexes, federation-actions) - Update index.js description to "lifecycle orchestration" - Data flow: add batch-broadcast delivery path README.md: - Remove stale "no custom emoji rendering" limitation - Update account enrichment to describe non-blocking behavior - Add 3 missing Mastodon API MongoDB collections - Add OAuth scope enforcement, rate limiting, token expiry, and CSRF to Mastodon Client API features --- CLAUDE.md | 9 +++++++-- README.md | 10 ++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 272dc98..36cbda1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,15 +14,19 @@ An Indiekit plugin that adds full ActivityPub federation via [Fedify](https://fe ## Architecture Overview ``` -index.js ← Plugin entry, route registration, syndicator +index.js ← Plugin entry, route registration, lifecycle orchestration ├── lib/federation-setup.js ← Fedify Federation instance, dispatchers, collections ├── lib/federation-bridge.js ← Express ↔ Fedify request/response bridge +├── lib/federation-actions.js ← Facade for controller federation access (context creation, actor resolution) ├── lib/inbox-listeners.js ← Fedify inbox listener registration + reply forwarding ├── lib/inbox-handlers.js ← Async inbox activity handlers (Create, Like, Announce, etc.) ├── lib/inbox-queue.js ← Persistent MongoDB-backed async inbox processing queue ├── lib/outbox-failure.js ← Outbox delivery failure handling (410 cleanup, 404 strikes, strike reset) +├── lib/batch-broadcast.js ← Shared batch delivery to followers (dedup, batching, logging) ├── lib/jf2-to-as2.js ← JF2 → ActivityStreams conversion (plain JSON + Fedify vocab) +├── lib/syndicator.js ← Indiekit syndicator factory (JF2→AS2, mention resolution, delivery) ├── lib/kv-store.js ← MongoDB-backed KvStore for Fedify (get/set/delete/list) +├── lib/init-indexes.js ← MongoDB index creation (idempotent startup) ├── lib/activity-log.js ← Activity logging to ap_activities ├── lib/item-processing.js ← Unified item processing pipeline (moderation, quotes, interactions, rendering) ├── lib/timeline-store.js ← Timeline item extraction + sanitization @@ -117,7 +121,8 @@ index.js ← Plugin entry, route registration, syndicat ## Data Flow ``` -Outbound: Indiekit post → syndicator.syndicate() → jf2ToAS2Activity() → ctx.sendActivity() → follower inboxes +Outbound: Indiekit post → syndicator.js syndicate() → jf2ToAS2Activity() → ctx.sendActivity() → follower inboxes + Broadcast (Update/Delete) → batch-broadcast.js → deduplicated shared inbox delivery Delivery failure → outbox-failure.js → 410: full cleanup | 404: strike system → eventual cleanup Inbound: Remote inbox POST → Fedify → inbox-listeners.js → ap_inbox_queue → inbox-handlers.js → MongoDB Reply forwarding: inbox-listeners.js checks if reply is to our post → ctx.forwardActivity() → follower inboxes diff --git a/README.md b/README.md index 7b6791f..69c644e 100644 --- a/README.md +++ b/README.md @@ -88,13 +88,17 @@ ActivityPub federation endpoint for [Indiekit](https://getindiekit.com), built o - URL auto-linkification and @mention extraction in posted content - Thread context (ancestors + descendants) - Remote profile resolution via Fedify WebFinger with follower/following/post counts from AP collections -- Account stats enrichment — embedded account data in timeline responses includes real counts +- Account stats enrichment — cached account data applied immediately; uncached accounts resolved in background - Favourite, boost, bookmark interactions federated via Fedify AP activities - Notifications with type filtering - Search across accounts, statuses, and hashtags with remote resolution - Domain blocks API - Timeline backfill from posts collection on startup (bookmarks, likes, reposts get synthesized content) - In-memory account stats cache (500 entries, 1h TTL) for performance +- OAuth2 scope enforcement — read/write scope validation on all API routes +- Rate limiting — configurable limits on API, auth, and app registration endpoints +- Access token expiry (1 hour) with refresh token rotation (90 days) +- PKCE (S256) and CSRF protection on authorization flow **Admin UI** - Dashboard with follower/following counts and recent activity @@ -318,6 +322,9 @@ The plugin creates these collections automatically: | `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 | +| `ap_oauth_apps` | Mastodon API client app registrations | +| `ap_oauth_tokens` | OAuth2 authorization codes and access tokens | +| `ap_markers` | Read position markers for Mastodon API clients | ## Supported Post Types @@ -411,7 +418,6 @@ This is not a bug — Fedify requires explicit opt-in for signed fetches. But it - **Single actor** — One fediverse identity per Indiekit instance - **No Authorized Fetch enforcement** — `.authorize()` disabled on actor dispatcher (see workarounds above) - **No image upload in reader** — Compose form is text-only -- **No custom emoji rendering** — Custom emoji shortcodes display as text - **In-process queue without Redis** — Activities may be lost on restart ## Acknowledgements