#![feature(try_blocks)] use std::collections::HashMap; use axum::{ extract::{Path, Query}, response::{AppendHeaders, IntoResponse as _}, routing::get, Json, Router, }; use puppy::{ actor::Actor, context, data::{PrivateKey, PublicKey}, get_local_ap_object, Key, }; use serde_json::json; #[tokio::main] async fn main() { let app = Router::new() .route( "/o/:ulid", get( |Path(raw_object_id): Path, req: axum::extract::Request| async move { eprintln!("req: {req:?}"); context::<_, puppy::Error>(|cx| try { let object_id = raw_object_id.parse::().unwrap(); let obj = get_local_ap_object(&cx, object_id).unwrap().to_json_ld(); ( AppendHeaders([("content-type", "application/activity+json")]), Json(obj).into_response(), ) }) .unwrap() }, ), ) .route( "/proxy", get(|Query(q): Query>| async move { let (key_pem, key_id) = context::<_, puppy::Error>(|cx| try { let actor = Actor::by_username(&cx, "riley")?.unwrap(); let (private, public) = cx .store() .get_mixin_many::<(PrivateKey, PublicKey)>(actor.key)?; (private.key_pem, public.key_id) }) .unwrap(); puppy::fetch::resolve(&key_pem, &key_id, &q["target"]) .await .unwrap() }), ) .route( "/.well-known/webfinger", get( |Query(q): Query>, req: axum::extract::Request| async move { eprintln!("req: {req:?}"); let Some(rest) = q["resource"].strip_prefix("acct:") else { panic!("{q:?}"); }; if rest == "riley@test.piss-on.me" { Json(json!({ "subject": "acct:riley@test.piss-on.me", "links": [{ "rel": "self", "type": "application/activity+json", "href": "https://test.piss-on.me/o/01HWG4BQJR23TWF12KVPBBP1HG", }], })) } else { panic!("{rest:?}") } }, ), ); let sock = tokio::net::TcpListener::bind("0.0.0.0:1312").await.unwrap(); axum::serve(sock, app).await.unwrap(); }