Alternative ATProto PDS implementation
1use atrium_api::app::bsky::actor; 2use axum::{Json, routing::post}; 3use constcat::concat; 4use diesel::prelude::*; 5 6use super::*; 7 8async fn put_preferences( 9 user: AuthenticatedUser, 10 State(db): State<Db>, 11 Json(input): Json<actor::put_preferences::Input>, 12) -> Result<()> { 13 let did = user.did(); 14 let json_string = 15 serde_json::to_string(&input.preferences).context("failed to serialize preferences")?; 16 17 // Use the db connection pool to execute the update 18 let conn = &mut db.get().context("failed to get database connection")?; 19 diesel::sql_query("UPDATE accounts SET private_prefs = ? WHERE did = ?") 20 .bind::<diesel::sql_types::Text, _>(json_string) 21 .bind::<diesel::sql_types::Text, _>(did) 22 .execute(conn) 23 .context("failed to update user preferences")?; 24 25 Ok(()) 26} 27 28async fn get_preferences( 29 user: AuthenticatedUser, 30 State(db): State<Db>, 31) -> Result<Json<actor::get_preferences::Output>> { 32 let did = user.did(); 33 let conn = &mut db.get().context("failed to get database connection")?; 34 35 #[derive(QueryableByName)] 36 struct Prefs { 37 #[diesel(sql_type = diesel::sql_types::Text)] 38 private_prefs: Option<String>, 39 } 40 41 let result = diesel::sql_query("SELECT private_prefs FROM accounts WHERE did = ?") 42 .bind::<diesel::sql_types::Text, _>(did) 43 .get_result::<Prefs>(conn) 44 .context("failed to fetch preferences")?; 45 46 if let Some(prefs_json) = result.private_prefs { 47 let prefs: actor::defs::Preferences = 48 serde_json::from_str(&prefs_json).context("failed to deserialize preferences")?; 49 50 Ok(Json( 51 actor::get_preferences::OutputData { preferences: prefs }.into(), 52 )) 53 } else { 54 Ok(Json( 55 actor::get_preferences::OutputData { 56 preferences: Vec::new(), 57 } 58 .into(), 59 )) 60 } 61} 62 63/// Register all actor endpoints. 64pub(crate) fn routes() -> Router<AppState> { 65 // AP /xrpc/app.bsky.actor.putPreferences 66 // AG /xrpc/app.bsky.actor.getPreferences 67 Router::new() 68 .route( 69 concat!("/", actor::put_preferences::NSID), 70 post(put_preferences), 71 ) 72 .route( 73 concat!("/", actor::get_preferences::NSID), 74 get(get_preferences), 75 ) 76}