activity-pub implementation

This commit is contained in:
2026-05-08 21:26:50 +02:00
parent 940c33047c
commit df71748897
50 changed files with 2724 additions and 97 deletions

View File

@@ -9,6 +9,21 @@ use tower_http::{services::ServeDir, trace::TraceLayer};
use crate::{handlers, state::AppState};
/// Build an ActivityPub router from the service, excluding routes that
/// conflict with HTML routes (/users/{id} and /users/{id}/following).
/// Those AP endpoints are still served via the federation middleware layer
/// applied to the whole AP router scope; the conflicting paths will need
/// content-negotiation wrappers added in Phase 5.
fn ap_routes(state: &AppState) -> Router {
let config = state.ap_service.federation_config();
Router::new()
.route("/.well-known/webfinger", routing::get(activitypub::webfinger::webfinger_handler))
.route("/users/{user_id}/inbox", routing::post(activitypub::inbox::inbox_handler))
.route("/users/{user_id}/outbox", routing::get(activitypub::outbox::outbox_handler))
.route("/users/{user_id}/followers", routing::get(activitypub::followers_handler::followers_handler))
.layer(config.middleware())
}
/// Simple global rate limiter: tracks request count per 60-second window.
/// Not per-IP — suitable for a low-traffic personal app.
#[derive(Clone)]
@@ -47,12 +62,14 @@ impl RateLimiter {
pub fn build_router(state: AppState) -> Router {
let rate_limit = state.app_ctx.config.rate_limit;
let ap_router = ap_routes(&state);
Router::new()
.merge(html_routes(rate_limit))
.merge(api_routes(rate_limit))
.nest_service("/static", ServeDir::new("static"))
.layer(TraceLayer::new_for_http())
.with_state(state)
.merge(ap_router)
}
fn html_routes(rate_limit: u64) -> Router<AppState> {
@@ -87,6 +104,18 @@ fn html_routes(rate_limit: u64) -> Router<AppState> {
"/users/{id}",
routing::get(handlers::html::get_user_profile),
)
.route(
"/users/{id}/follow",
routing::post(handlers::html::follow_remote_user),
)
.route(
"/users/{id}/unfollow",
routing::post(handlers::html::unfollow_remote_user),
)
.route(
"/users/{id}/following-list",
routing::get(handlers::html::get_following_page),
)
.merge(auth)
.route(
"/reviews/new",