diff --git a/Cargo.lock b/Cargo.lock index 4732bb6..ee6e375 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2017,9 +2017,9 @@ dependencies = [ [[package]] name = "k-ap" -version = "0.4.0" +version = "0.4.4" source = "sparse+https://git.gabrielkaszewski.dev/api/packages/GKaszewski/cargo/" -checksum = "ccaa914953bfd45ea206e11826da8f61ce1fbe02f8fe0622880527046ad6ae24" +checksum = "daec6ce514e07fc9c6e39a780f3144292534008a2c16c1645f131fad877c7894" dependencies = [ "activitypub_federation", "anyhow", @@ -4570,7 +4570,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] diff --git a/crates/adapters/activitypub/Cargo.toml b/crates/adapters/activitypub/Cargo.toml index 8497b71..d2abb7f 100644 --- a/crates/adapters/activitypub/Cargo.toml +++ b/crates/adapters/activitypub/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -k-ap = { version = "0.4.0", registry = "gitea" } +k-ap = { version = "0.4.4", registry = "gitea" } domain = { workspace = true } url = { workspace = true } serde = { workspace = true } diff --git a/crates/adapters/event-payload/src/lib.rs b/crates/adapters/event-payload/src/lib.rs index c719659..9ab789f 100644 --- a/crates/adapters/event-payload/src/lib.rs +++ b/crates/adapters/event-payload/src/lib.rs @@ -97,6 +97,11 @@ pub enum EventPayload { owner_user_id: String, follower_inbox_url: String, }, + FederationOutboundFollowAccepted { + local_user_id: String, + remote_actor_url: String, + outbox_url: Option, + }, } impl EventPayload { @@ -124,6 +129,7 @@ impl EventPayload { Self::MentionReceived { .. } => "mentions.received", Self::FederationDeliveryRequested { .. } => "federation.delivery.requested", Self::FederationBackfillRequested { .. } => "federation.backfill.requested", + Self::FederationOutboundFollowAccepted { .. } => "federation.outbound_follow.accepted", } } } @@ -421,7 +427,8 @@ impl TryFrom for DomainEvent { author_user_id: UserId::from_uuid(parse_uuid(&author_user_id, "author_user_id")?), }, EventPayload::FederationDeliveryRequested { .. } - | EventPayload::FederationBackfillRequested { .. } => { + | EventPayload::FederationBackfillRequested { .. } + | EventPayload::FederationOutboundFollowAccepted { .. } => { return Err(DomainError::Internal( "federation infrastructure event — not a domain event".into(), )); diff --git a/crates/adapters/postgres-federation/Cargo.toml b/crates/adapters/postgres-federation/Cargo.toml index 179de97..8abfa69 100644 --- a/crates/adapters/postgres-federation/Cargo.toml +++ b/crates/adapters/postgres-federation/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -k-ap = { version = "0.4.0", registry = "gitea" } +k-ap = { version = "0.4.4", registry = "gitea" } sqlx = { workspace = true } uuid = { workspace = true } chrono = { workspace = true } diff --git a/crates/bootstrap/Cargo.toml b/crates/bootstrap/Cargo.toml index 963a3f7..add8b39 100644 --- a/crates/bootstrap/Cargo.toml +++ b/crates/bootstrap/Cargo.toml @@ -14,7 +14,7 @@ postgres = { workspace = true } postgres-search = { workspace = true } postgres-federation = { workspace = true } activitypub = { workspace = true } -k-ap = { version = "0.4.0", registry = "gitea" } +k-ap = { version = "0.4.4", registry = "gitea" } serde_json = { workspace = true } anyhow = { workspace = true } nats = { workspace = true } diff --git a/crates/bootstrap/src/factory.rs b/crates/bootstrap/src/factory.rs index 35e7085..67c764f 100644 --- a/crates/bootstrap/src/factory.rs +++ b/crates/bootstrap/src/factory.rs @@ -70,6 +70,20 @@ impl k_ap::data::EventPublisher for KapPublisher { follower_inbox_url, })?, ), + FederationEvent::OutboundFollowAccepted { + local_user_id, + remote_actor_url, + outbox_url, + } => ( + "federation.outbound_follow.accepted", + serde_json::to_vec( + &event_payload::EventPayload::FederationOutboundFollowAccepted { + local_user_id: local_user_id.to_string(), + remote_actor_url, + outbox_url, + }, + )?, + ), FederationEvent::DeliveryFailed { inbox, error, .. } => { tracing::warn!(%inbox, %error, "AP delivery failed permanently"); return Ok(()); diff --git a/crates/worker/Cargo.toml b/crates/worker/Cargo.toml index 4cfd9b1..bb77b8d 100644 --- a/crates/worker/Cargo.toml +++ b/crates/worker/Cargo.toml @@ -13,7 +13,7 @@ application = { workspace = true } nats = { workspace = true } event-transport = { workspace = true } event-payload = { workspace = true } -k-ap = { version = "0.4.0", registry = "gitea" } +k-ap = { version = "0.4.4", registry = "gitea" } activitypub = { workspace = true } postgres = { workspace = true } postgres-federation = { workspace = true } diff --git a/crates/worker/src/main.rs b/crates/worker/src/main.rs index a67afe9..1815c04 100644 --- a/crates/worker/src/main.rs +++ b/crates/worker/src/main.rs @@ -104,6 +104,22 @@ async fn main() { .await; result } + EventPayload::FederationOutboundFollowAccepted { + remote_actor_url, + outbox_url, + .. + } => { + if let Some(outbox) = outbox_url { + infra + .raw_ap_service + .import_remote_outbox(&outbox, &remote_actor_url) + .await + .map_err(|e| DomainError::Internal(e.to_string())) + } else { + tracing::info!(%remote_actor_url, "outbound follow accepted but no outbox URL — skipping backfill"); + Ok(()) + } + } // ── domain events ────────────────────────────────────── p => match DomainEvent::try_from(p) {