SsrfVerifier rejects private/reserved IPs (loopback, RFC1918, link-local,
CGNAT, ULA) on all federation fetches. Raw reqwest calls in webfinger and
backfill also validated. Debug mode bypasses via PermissiveVerifier.
Closes#4
Adds fetched_at to RemoteActor, configurable TTL via builder
(.actor_cache_ttl_secs, default 24h), and get_or_refresh_remote_actor
helper that re-fetches stale actors from origin.
Closes#3
Builder: .signed_fetch_actor_id(uuid) sets instance-level signing actor.
Service: .signed_fetch(&url) performs a signed GET returning raw JSON.
Closes#2
These paths need content negotiation in real apps (AP JSON vs UI JSON).
k-ap can't serve the UI half, so the consuming app owns the route and
calls actor_json/followers_collection_json/following_collection_json
to produce the AP response.
The route conflict caused a panic when thoughts mounted its own
/users/{username}/... routes alongside service.router().
router() now registers only what k-ap fully owns:
- POST /inbox, POST /users/{id}/inbox (signature verification)
- GET /users/{id}/outbox
- GET /users/{id}/featured
- GET /.well-known/webfinger, nodeinfo, /nodeinfo/2.0
Undo(Announce): now removes announce record from ActorRepository and
calls ApObjectHandler::on_announce_removed (default no-op, override
to decrement boost counts). Announce counts no longer drift.
Undo(Block): now logged at info level instead of silently ignored.
No automatic relationship restoration (spec doesn't require it).
AddActivity: now uses object["id"] as the stable ap_id (same as
CreateActivity), falling back to activity id only if object has no
id field. Fixes keying watchlist/collection items by the wrong id.
Featured collection: GET /users/{id}/featured now served by the router.
ApContentReader::get_featured_objects() has a default empty-list impl
— override to expose pinned posts without any breaking changes.
#15 @context security vocab: actor JSON now uses actor_ap_context()
which includes W3C security vocab + Mastodon toot extensions
(manuallyApprovesFollowers, discoverable, featured).
Applied to actor_handler, actor_json(), broadcast_actor_update().
Activity JSON keeps plain AS context (no security vocab needed).
#17 HTTP Digest (documented, no code change): production mode
(debug=false) REQUIRES Digest header on inbound POSTs via
require_digest() in the non-compat normalization config.
Added doc comment to ApFederationConfig::new() to clarify.
#26 Integration tests: 3 new tokio tests in src/tests/integration.rs
using in-memory trait stubs. Tests cover:
- check_guards idempotency (duplicate activity rejected)
- check_guards domain block (blocked domain skipped)
- extract_and_dispatch_mentions (on_mention called for local actor)