fix: AP protocol correctness gaps
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.
This commit is contained in:
42
src/featured_handler.rs
Normal file
42
src/featured_handler.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use activitypub_federation::{axum::json::FederationJson, config::Data};
|
||||
use axum::extract::Path;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::data::FederationData;
|
||||
use crate::error::Error;
|
||||
use crate::urls::AP_CONTEXT;
|
||||
|
||||
/// Serves the `featured` (pinned posts) `OrderedCollection` for a local user.
|
||||
///
|
||||
/// Remote servers follow the `featured` link from the actor JSON and expect
|
||||
/// an `OrderedCollection` whose `orderedItems` are the AP URLs of pinned objects.
|
||||
/// The handler calls [`ApContentReader::get_featured_objects`] — override that
|
||||
/// method to expose your pinned posts.
|
||||
pub async fn featured_handler(
|
||||
Path(user_id_str): Path<String>,
|
||||
data: Data<FederationData>,
|
||||
) -> Result<FederationJson<serde_json::Value>, Error> {
|
||||
let user_id = uuid::Uuid::parse_str(&user_id_str)
|
||||
.map_err(|_| Error::not_found(anyhow::anyhow!("user not found")))?;
|
||||
|
||||
data.user_repo
|
||||
.find_by_id(user_id)
|
||||
.await
|
||||
.map_err(Error::from)?
|
||||
.ok_or_else(|| Error::not_found(anyhow::anyhow!("user not found")))?;
|
||||
|
||||
let featured_url = format!("{}/users/{}/featured", data.base_url, user_id_str);
|
||||
let items = data
|
||||
.content_reader
|
||||
.get_featured_objects(user_id)
|
||||
.await
|
||||
.map_err(|e| Error::from(anyhow::anyhow!("{}", e)))?;
|
||||
|
||||
Ok(FederationJson(json!({
|
||||
"@context": AP_CONTEXT,
|
||||
"type": "OrderedCollection",
|
||||
"id": featured_url,
|
||||
"totalItems": items.len(),
|
||||
"orderedItems": items.iter().map(|u| u.as_str()).collect::<Vec<_>>(),
|
||||
})))
|
||||
}
|
||||
Reference in New Issue
Block a user