Alternative ATProto PDS implementation
1/// HACK: store private user preferences in the PDS.
2///
3/// We shouldn't have to know about any bsky endpoints to store private user data.
4/// This will _very likely_ be changed in the future.
5use atrium_api::app::bsky::actor;
6use axum::{
7 Json, Router,
8 extract::State,
9 routing::{get, post},
10};
11use constcat::concat;
12
13use crate::auth::AuthenticatedUser;
14
15use super::serve::*;
16
17async fn put_preferences(
18 user: AuthenticatedUser,
19 State(actor_pools): State<std::collections::HashMap<String, ActorStorage>>,
20 Json(input): Json<actor::put_preferences::Input>,
21) -> Result<()> {
22 let did = user.did();
23 // let json_string =
24 // serde_json::to_string(&input.preferences).context("failed to serialize preferences")?;
25
26 // let conn = &mut actor_pools
27 // .get(&did)
28 // .context("failed to get actor pool")?
29 // .repo
30 // .get()
31 // .await
32 // .expect("failed to get database connection");
33 // conn.interact(move |conn| {
34 // diesel::update(accounts::table)
35 // .filter(accounts::did.eq(did))
36 // .set(accounts::private_prefs.eq(json_string))
37 // .execute(conn)
38 // .context("failed to update user preferences")
39 // });
40 todo!("Use actor_store's preferences writer instead");
41 // let mut actor_store = ActorStore::from_actor_pools(&did, &actor_pools).await;
42 // let values = actor::defs::Preferences {
43 // private_prefs: Some(json_string),
44 // ..Default::default()
45 // };
46 // let namespace = actor::defs::PreferencesNamespace::Private;
47 // let scope = actor::defs::PreferencesScope::User;
48 // actor_store.pref.put_preferences(values, namespace, scope);
49
50 Ok(())
51}
52
53async fn get_preferences(
54 user: AuthenticatedUser,
55 State(actor_pools): State<std::collections::HashMap<String, ActorStorage>>,
56) -> Result<Json<actor::get_preferences::Output>> {
57 let did = user.did();
58 // let conn = &mut actor_pools
59 // .get(&did)
60 // .context("failed to get actor pool")?
61 // .repo
62 // .get()
63 // .await
64 // .expect("failed to get database connection");
65
66 // #[derive(QueryableByName)]
67 // struct Prefs {
68 // #[diesel(sql_type = diesel::sql_types::Text)]
69 // private_prefs: Option<String>,
70 // }
71
72 // let result = conn
73 // .interact(move |conn| {
74 // diesel::sql_query("SELECT private_prefs FROM accounts WHERE did = ?")
75 // .bind::<diesel::sql_types::Text, _>(did)
76 // .get_result::<Prefs>(conn)
77 // })
78 // .await
79 // .expect("failed to fetch preferences");
80
81 // if let Some(prefs_json) = result.private_prefs {
82 // let prefs: actor::defs::Preferences =
83 // serde_json::from_str(&prefs_json).context("failed to deserialize preferences")?;
84
85 // Ok(Json(
86 // actor::get_preferences::OutputData { preferences: prefs }.into(),
87 // ))
88 // } else {
89 // Ok(Json(
90 // actor::get_preferences::OutputData {
91 // preferences: Vec::new(),
92 // }
93 // .into(),
94 // ))
95 // }
96 todo!("Use actor_store's preferences writer instead");
97}
98
99/// Register all actor endpoints.
100pub(crate) fn routes() -> Router<AppState> {
101 // AP /xrpc/app.bsky.actor.putPreferences
102 // AG /xrpc/app.bsky.actor.getPreferences
103 Router::new()
104 .route(
105 concat!("/", actor::put_preferences::NSID),
106 post(put_preferences),
107 )
108 .route(
109 concat!("/", actor::get_preferences::NSID),
110 get(get_preferences),
111 )
112}