this repo has no description
1use crate::auth::BearerAuthAdmin;
2use crate::state::AppState;
3use axum::{
4 Json,
5 extract::{Query, RawQuery, State},
6 http::StatusCode,
7 response::{IntoResponse, Response},
8};
9use serde::{Deserialize, Serialize};
10use serde_json::json;
11use tracing::error;
12
13#[derive(Deserialize)]
14pub struct GetAccountInfoParams {
15 pub did: String,
16}
17
18#[derive(Serialize)]
19#[serde(rename_all = "camelCase")]
20pub struct AccountInfo {
21 pub did: String,
22 pub handle: String,
23 pub email: Option<String>,
24 pub indexed_at: String,
25 pub invite_note: Option<String>,
26 pub invites_disabled: bool,
27 pub email_verified_at: Option<String>,
28 pub deactivated_at: Option<String>,
29}
30
31#[derive(Serialize)]
32#[serde(rename_all = "camelCase")]
33pub struct GetAccountInfosOutput {
34 pub infos: Vec<AccountInfo>,
35}
36
37pub async fn get_account_info(
38 State(state): State<AppState>,
39 _auth: BearerAuthAdmin,
40 Query(params): Query<GetAccountInfoParams>,
41) -> Response {
42 let did = params.did.trim();
43 if did.is_empty() {
44 return (
45 StatusCode::BAD_REQUEST,
46 Json(json!({"error": "InvalidRequest", "message": "did is required"})),
47 )
48 .into_response();
49 }
50 let result = sqlx::query!(
51 r#"
52 SELECT did, handle, email, created_at
53 FROM users
54 WHERE did = $1
55 "#,
56 did
57 )
58 .fetch_optional(&state.db)
59 .await;
60 match result {
61 Ok(Some(row)) => (
62 StatusCode::OK,
63 Json(AccountInfo {
64 did: row.did,
65 handle: row.handle,
66 email: row.email,
67 indexed_at: row.created_at.to_rfc3339(),
68 invite_note: None,
69 invites_disabled: false,
70 email_verified_at: None,
71 deactivated_at: None,
72 }),
73 )
74 .into_response(),
75 Ok(None) => (
76 StatusCode::NOT_FOUND,
77 Json(json!({"error": "AccountNotFound", "message": "Account not found"})),
78 )
79 .into_response(),
80 Err(e) => {
81 error!("DB error in get_account_info: {:?}", e);
82 (
83 StatusCode::INTERNAL_SERVER_ERROR,
84 Json(json!({"error": "InternalError"})),
85 )
86 .into_response()
87 }
88 }
89}
90
91pub async fn get_account_infos(
92 State(state): State<AppState>,
93 _auth: BearerAuthAdmin,
94 RawQuery(raw_query): RawQuery,
95) -> Response {
96 let dids = crate::util::parse_repeated_query_param(raw_query.as_deref(), "dids");
97 if dids.is_empty() {
98 return (
99 StatusCode::BAD_REQUEST,
100 Json(json!({"error": "InvalidRequest", "message": "dids is required"})),
101 )
102 .into_response();
103 }
104 let mut infos = Vec::new();
105 for did in &dids {
106 if did.is_empty() {
107 continue;
108 }
109 let result = sqlx::query!(
110 r#"
111 SELECT did, handle, email, created_at
112 FROM users
113 WHERE did = $1
114 "#,
115 did
116 )
117 .fetch_optional(&state.db)
118 .await;
119 if let Ok(Some(row)) = result {
120 infos.push(AccountInfo {
121 did: row.did,
122 handle: row.handle,
123 email: row.email,
124 indexed_at: row.created_at.to_rfc3339(),
125 invite_note: None,
126 invites_disabled: false,
127 email_verified_at: None,
128 deactivated_at: None,
129 });
130 }
131 }
132 (StatusCode::OK, Json(GetAccountInfosOutput { infos })).into_response()
133}