wiki: add Inbound Activity Handling page

2026-05-29 02:09:58 +00:00
parent e2ab6f14d1
commit 2b434d617a

@@ -0,0 +1,73 @@
# Inbound Activity Handling
k-ap handles the following inbound activities out of the box. All arrive via `POST /inbox` or `POST /users/{id}/inbox`, after HTTP signature verification.
---
## Handled activities
| Activity | What k-ap does |
|----------|----------------|
| `Follow` | Saves follower with `Pending` status; checks blocklist first |
| `Accept` | Updates outbound following status to `Accepted` |
| `Reject` | Updates outbound following status to `Rejected` |
| `Undo(Follow)` | Removes the follower record; calls `on_actor_removed` |
| `Undo(Like)` | Calls `on_unlike` |
| `Undo(Announce)` | Removes announce record from `ActorRepository`; calls `on_announce_removed` |
| `Undo(Add)` | No-op |
| `Undo(Block)` | No-op |
| `Create` | Calls `on_create` with the wrapped object JSON; dispatches mentions |
| `Update` | Calls `on_update` with the wrapped object JSON; dispatches mentions |
| `Delete` | Calls `on_delete` with the object URL; if object is an actor, calls `on_actor_removed` |
| `Announce` | Records in `ActorRepository`; calls `on_announce_received` (local object) or `on_announce_of_remote` (remote object) |
| `Like` | Calls `on_like` |
| `Add` | Calls `on_create` with the object JSON |
| `Block` | No-op (you may surface this in your UI separately) |
| `Move` | Verifies `alsoKnownAs`, migrates follower records, re-follows in background |
---
## Deduplication
Before any handler is called, k-ap calls `ActivityRepository::is_activity_processed` with the activity's `id`. If already processed, the handler is skipped and the inbox returns 200. After successful processing, `mark_activity_processed` is called.
This makes inbound delivery safe to retry — the sender can retry on network failure without causing duplicate effects.
---
## Mention dispatch
For `Create` and `Update` activities, k-ap extracts the `tag` array from the wrapped object and looks for `{"type":"Mention","href":"<local-actor-url>"}` entries. For each mention that resolves to a local user, `ApObjectHandler::on_mention` is called with the object's AP ID, the local user's UUID, and the mentioning actor's URL.
`on_mention` failures are logged and swallowed — a broken notification must not cause the activity to be rejected.
---
## Move (account migration)
When a `Move` activity is received:
1. k-ap fetches the target actor's JSON
2. Verifies that the target's `alsoKnownAs` array contains the source actor's URL (all aliases checked)
3. Calls `FollowRepository::migrate_follower_actor` to update follower records
4. Spawns a background task (non-blocking) to re-follow the new actor on behalf of local users who followed the old one
Step 4 runs in the background so the inbox handler returns immediately.
---
## Error responses
4xx responses sent to remote servers use generic messages. Internal error details are only logged via `tracing`, never sent to clients. This prevents information leakage to potentially adversarial servers.
---
## Body limit
Both inbox routes enforce a **1 MB body limit** via axum's `DefaultBodyLimit`. Oversized payloads are rejected with 413 before any processing.
---
## Actor types accepted
k-ap accepts activities from `Person`, `Service`, `Application`, `Organization`, and `Group` actors.