···
94
+
fn bad_request_handler_resolve_handle(err: poem::Error) -> JustDidResponse {
95
+
JustDidResponse::BadRequest(Json(XrpcErrorResponseObject {
96
+
error: "InvalidRequest".to_string(),
97
+
message: format!("Bad request, here's some info that maybe should not be exposed: {err}"),
struct FoundRecordResponseObject {
···
193
+
#[oai(example = true)]
194
+
struct FoundDidResponseObject {
195
+
/// the DID, bi-directionally verified if using Slingshot
198
+
impl Example for FoundDidResponseObject {
199
+
fn example() -> Self {
200
+
Self { did: example_did() }
204
+
#[derive(ApiResponse)]
205
+
#[oai(bad_request_handler = "bad_request_handler_resolve_handle")]
206
+
enum JustDidResponse {
207
+
/// Resolution succeeded
208
+
#[oai(status = 200)]
209
+
Ok(Json<FoundDidResponseObject>),
210
+
/// Bad request, failed to resolve, or failed to verify
212
+
/// `error` will be one of `InvalidRequest`, `HandleNotFound`.
213
+
#[oai(status = 400)]
214
+
BadRequest(XrpcError),
215
+
/// Something went wrong trying to complete the request
216
+
#[oai(status = 500)]
217
+
ServerError(XrpcError),
cache: HybridCache<String, CachedRecord>,
···
352
+
/// com.atproto.identity.resolveHandle
354
+
/// Resolves an atproto [`handle`](https://atproto.com/guides/glossary#handle)
355
+
/// (hostname) to a [`DID`](https://atproto.com/guides/glossary#did-decentralized-id).
357
+
/// Compatibility note: **Slingshot will _always_ bi-directionally verify
358
+
/// against the DID document**, which is optional by the authoritative
359
+
/// lexicon. You can trust the `DID` returned from this endpoint without
360
+
/// further checks, but this may not hold if you switch from Slingshot to a
361
+
/// different service offering this query.
363
+
/// See also the [canonical `com.atproto` XRPC documentation](https://docs.bsky.app/docs/api/com-atproto-identity-resolve-handle)
364
+
/// that this endpoint aims to be compatible with.
366
+
path = "/com.atproto.identity.resolveHandle",
368
+
tag = "ApiTags::ComAtproto"
370
+
async fn resolve_handle(
372
+
/// The handle to resolve.
373
+
#[oai(example = "example_handle")]
374
+
Query(handle): Query<String>,
375
+
) -> JustDidResponse {
376
+
let Ok(handle) = Handle::new(handle) else {
377
+
return JustDidResponse::BadRequest(xrpc_error("InvalidRequest", "not a valid handle"));
380
+
let Ok(alleged_did) = self.identity.handle_to_did(handle.clone()).await else {
381
+
return JustDidResponse::ServerError(xrpc_error("Failed", "Could not resolve handle"));
384
+
let Some(alleged_did) = alleged_did else {
385
+
return JustDidResponse::BadRequest(xrpc_error(
387
+
"Could not resolve handle to a DID",
391
+
let Ok(partial_doc) = self.identity.did_to_partial_mini_doc(&alleged_did).await else {
392
+
return JustDidResponse::ServerError(xrpc_error("Failed", "Could not fetch DID doc"));
395
+
let Some(partial_doc) = partial_doc else {
396
+
return JustDidResponse::BadRequest(xrpc_error(
398
+
"Resolved handle but could not find DID doc for the DID",
402
+
if partial_doc.unverified_handle != handle {
403
+
return JustDidResponse::BadRequest(xrpc_error(
405
+
"Resolved handle failed bi-directional validation",
409
+
JustDidResponse::Ok(Json(FoundDidResponseObject {
410
+
did: alleged_did.to_string(),
/// com.bad-example.identity.resolveMiniDoc