fix(federation): fix 27 AP bugs, gaps, and inconsistencies
Round 1 — 18 bug fixes:
- remote likes/boosts now persist in engagement tables
- intern_remote_actor uses name@domain, expanded username to VARCHAR(255)
- PgRemoteActorRepository upsert/find now handles all fields
- update_following_status no longer a no-op, count_followers counts all
- accept/reject follow publishes event before DB mark (atomicity)
- fetch_outbox_page follows pagination via next links
- actor URL canonicalized to /users/{uuid}
- content_to_html escapes single quotes
- WebFinger accepts application/ld+json type
- try_from_ap accepts Article and Page object types
- feed SQL uses parameterized viewer UUID instead of format!
- content cap raised from 500 to 5000 chars
- also_known_as changed from Option<String> to Vec<String>
- connections fetch always triggers from page 1
Round 2 — 9 gap fixes:
- on_announce_removed handler deletes boost row on Undo(Announce)
- on_update handles Person/Service/Group actor profile updates
- sync_remote_actor_to_user syncs remote_actors → users on create/update
- FederationBlockPort: block_by_username sends Block activity to remote
- domain RemoteActor gains inbox_url, shared_inbox_url fields
- remote_actors attachment column (JSONB) with read/write
- .well-known/host-meta endpoint
- 256KB body limit on AP inbox routes
- outbox cleanup job (7-day retention, hourly sweep)
This commit is contained in:
@@ -126,11 +126,17 @@ pub async fn build(cfg: &Config) -> Infrastructure {
|
||||
// 3. ActivityPub federation
|
||||
let connections_repo = Arc::new(PgRemoteActorConnectionRepository::new(pool.clone()));
|
||||
let fed_repo = Arc::new(PostgresFederationRepository::new(pool.clone()));
|
||||
let likes: Arc<dyn domain::ports::LikeRepository> =
|
||||
Arc::new(postgres::like::PgLikeRepository::new(pool.clone()));
|
||||
let boosts: Arc<dyn domain::ports::BoostRepository> =
|
||||
Arc::new(postgres::boost::PgBoostRepository::new(pool.clone()));
|
||||
let ap_handler = Arc::new(ThoughtsObjectHandler::new(
|
||||
Arc::new(PgActivityPubRepository::new(pool.clone())),
|
||||
&cfg.base_url,
|
||||
Some(event_publisher.clone()),
|
||||
Arc::new(postgres::tag::PgTagRepository::new(pool.clone())),
|
||||
likes.clone(),
|
||||
boosts.clone(),
|
||||
));
|
||||
let mut ap_builder = ActivityPubService::builder(cfg.base_url.clone())
|
||||
.activity_repo(fed_repo.clone())
|
||||
@@ -181,8 +187,8 @@ pub async fn build(cfg: &Config) -> Infrastructure {
|
||||
let state = AppState {
|
||||
users: Arc::new(postgres::user::PgUserRepository::new(pool.clone())),
|
||||
thoughts: Arc::new(postgres::thought::PgThoughtRepository::new(pool.clone())),
|
||||
likes: Arc::new(postgres::like::PgLikeRepository::new(pool.clone())),
|
||||
boosts: Arc::new(postgres::boost::PgBoostRepository::new(pool.clone())),
|
||||
likes: likes.clone(),
|
||||
boosts: boosts.clone(),
|
||||
follows: Arc::new(postgres::follow::PgFollowRepository::new(pool.clone())),
|
||||
blocks: Arc::new(postgres::block::PgBlockRepository::new(pool.clone())),
|
||||
tags: Arc::new(postgres::tag::PgTagRepository::new(pool.clone())),
|
||||
|
||||
@@ -35,8 +35,13 @@ async fn main() {
|
||||
.allow_headers(tower_http::cors::Any)
|
||||
};
|
||||
|
||||
let ap_router = infra
|
||||
.ap_service
|
||||
.router::<presentation::state::AppState>()
|
||||
.layer(axum::extract::DefaultBodyLimit::max(256 * 1024));
|
||||
|
||||
let base = presentation::routes::router()
|
||||
.merge(infra.ap_service.router::<presentation::state::AppState>())
|
||||
.merge(ap_router)
|
||||
.with_state(infra.state)
|
||||
.layer(cors);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user