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:
@@ -222,13 +222,12 @@ impl FollowRepository for PostgresFederationRepository {
|
||||
}
|
||||
|
||||
async fn count_followers(&self, local_user_id: uuid::Uuid) -> Result<usize> {
|
||||
let n: i64 = sqlx::query_scalar(
|
||||
"SELECT COUNT(*) FROM federation_followers WHERE local_user_id=$1 AND status='accepted'",
|
||||
)
|
||||
.bind(local_user_id)
|
||||
.fetch_one(&self.pool)
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))?;
|
||||
let n: i64 =
|
||||
sqlx::query_scalar("SELECT COUNT(*) FROM federation_followers WHERE local_user_id=$1")
|
||||
.bind(local_user_id)
|
||||
.fetch_one(&self.pool)
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))?;
|
||||
Ok(n as usize)
|
||||
}
|
||||
|
||||
@@ -428,11 +427,24 @@ impl FollowRepository for PostgresFederationRepository {
|
||||
|
||||
async fn update_following_status(
|
||||
&self,
|
||||
_local_user_id: uuid::Uuid,
|
||||
_remote_actor_url: &str,
|
||||
_status: FollowingStatus,
|
||||
local_user_id: uuid::Uuid,
|
||||
remote_actor_url: &str,
|
||||
status: FollowingStatus,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
let s = match status {
|
||||
FollowingStatus::Pending => "pending",
|
||||
FollowingStatus::Accepted => "accepted",
|
||||
};
|
||||
sqlx::query(
|
||||
"UPDATE federation_following SET status=$3 WHERE local_user_id=$1 AND remote_actor_url=$2",
|
||||
)
|
||||
.bind(local_user_id)
|
||||
.bind(remote_actor_url)
|
||||
.bind(s)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
async fn get_following_outbox_url(
|
||||
@@ -743,7 +755,7 @@ impl PostgresApUserRepository {
|
||||
}
|
||||
|
||||
fn row_to_ap_user(&self, r: UserRow) -> ApUser {
|
||||
let profile_url = url::Url::parse(&format!("{}/users/{}", self.base_url, r.username)).ok();
|
||||
let profile_url = url::Url::parse(&format!("{}/users/{}", self.base_url, r.id)).ok();
|
||||
let avatar_url = r.avatar_url.and_then(|u| url::Url::parse(&u).ok());
|
||||
let banner_url = r.header_url.and_then(|u| url::Url::parse(&u).ok());
|
||||
ApUser {
|
||||
|
||||
Reference in New Issue
Block a user