this repo has no description
1use crate::api::repo::record::create_record_internal; 2use crate::state::AppState; 3use axum::{ 4 Json, 5 extract::State, 6 http::StatusCode, 7 response::{IntoResponse, Response}, 8}; 9use serde::{Deserialize, Serialize}; 10use serde_json::json; 11use tracing::{error, info}; 12 13#[derive(Deserialize)] 14#[serde(rename_all = "camelCase")] 15pub struct CreateProfileInput { 16 pub did: String, 17 pub display_name: Option<String>, 18 pub description: Option<String>, 19} 20 21#[derive(Deserialize)] 22#[serde(rename_all = "camelCase")] 23pub struct CreateRecordAdminInput { 24 pub did: String, 25 pub collection: String, 26 pub rkey: Option<String>, 27 pub record: serde_json::Value, 28} 29 30#[derive(Serialize)] 31#[serde(rename_all = "camelCase")] 32pub struct CreateProfileOutput { 33 pub uri: String, 34 pub cid: String, 35} 36 37pub async fn create_profile( 38 State(state): State<AppState>, 39 headers: axum::http::HeaderMap, 40 Json(input): Json<CreateProfileInput>, 41) -> Response { 42 let auth_header = headers.get("Authorization"); 43 if auth_header.is_none() { 44 return ( 45 StatusCode::UNAUTHORIZED, 46 Json(json!({"error": "AuthenticationRequired"})), 47 ) 48 .into_response(); 49 } 50 51 let did = input.did.trim(); 52 if did.is_empty() { 53 return ( 54 StatusCode::BAD_REQUEST, 55 Json(json!({"error": "InvalidRequest", "message": "did is required"})), 56 ) 57 .into_response(); 58 } 59 60 let mut profile_record = json!({ 61 "$type": "app.bsky.actor.profile" 62 }); 63 64 if let Some(display_name) = &input.display_name { 65 profile_record["displayName"] = json!(display_name); 66 } 67 if let Some(description) = &input.description { 68 profile_record["description"] = json!(description); 69 } 70 71 match create_record_internal( 72 &state, 73 did, 74 "app.bsky.actor.profile", 75 "self", 76 &profile_record, 77 ) 78 .await 79 { 80 Ok((uri, commit_cid)) => { 81 info!(did = %did, uri = %uri, "Created profile for user"); 82 ( 83 StatusCode::OK, 84 Json(CreateProfileOutput { 85 uri, 86 cid: commit_cid.to_string(), 87 }), 88 ) 89 .into_response() 90 } 91 Err(e) => { 92 error!("Failed to create profile for {}: {}", did, e); 93 ( 94 StatusCode::INTERNAL_SERVER_ERROR, 95 Json(json!({"error": "InternalError", "message": e})), 96 ) 97 .into_response() 98 } 99 } 100} 101 102pub async fn create_record_admin( 103 State(state): State<AppState>, 104 headers: axum::http::HeaderMap, 105 Json(input): Json<CreateRecordAdminInput>, 106) -> Response { 107 let auth_header = headers.get("Authorization"); 108 if auth_header.is_none() { 109 return ( 110 StatusCode::UNAUTHORIZED, 111 Json(json!({"error": "AuthenticationRequired"})), 112 ) 113 .into_response(); 114 } 115 116 let did = input.did.trim(); 117 if did.is_empty() { 118 return ( 119 StatusCode::BAD_REQUEST, 120 Json(json!({"error": "InvalidRequest", "message": "did is required"})), 121 ) 122 .into_response(); 123 } 124 125 let rkey = input 126 .rkey 127 .unwrap_or_else(|| chrono::Utc::now().format("%Y%m%d%H%M%S%f").to_string()); 128 129 match create_record_internal(&state, did, &input.collection, &rkey, &input.record).await { 130 Ok((uri, commit_cid)) => { 131 info!(did = %did, uri = %uri, "Admin created record"); 132 ( 133 StatusCode::OK, 134 Json(CreateProfileOutput { 135 uri, 136 cid: commit_cid.to_string(), 137 }), 138 ) 139 .into_response() 140 } 141 Err(e) => { 142 error!("Failed to create record for {}: {}", did, e); 143 ( 144 StatusCode::INTERNAL_SERVER_ERROR, 145 Json(json!({"error": "InternalError", "message": e})), 146 ) 147 .into_response() 148 } 149 } 150}