didbot_serve/routes/
session.rs1use super::*;
2
3const GET_SESSION_PATH: &str = "/xrpc/com.atproto.server.getSession";
5
6const INVALID_HANDLE: &str = "handle.invalid";
8
9pub(crate) async fn get_session(State(state): State<AppState>, headers: HeaderMap) -> Response {
18 match session(&state, &headers) {
19 Ok(body) => Json(body).into_response(),
20 Err(err) => err.into_response(),
21 }
22}
23
24fn session(state: &AppState, headers: &HeaderMap) -> Result<serde_json::Value, ApiError> {
25 require_lifecycle(state, |p| p.serves_reads, "com.atproto.server.getSession")?;
26 state.estop.check_use(EstopRefusal::Operation)?;
27 let writer = auth::require_agent_token_or_dpop(
28 state.registry.as_ref(),
29 &state.oauth,
30 headers,
31 "GET",
32 GET_SESSION_PATH,
33 )?;
34 let did = writer.did();
35 let account = state
36 .registry
37 .account(did)
38 .ok_or_else(|| ApiError::repo_not_found(did))?;
39 let document = state.registry.did_document(account.did.host());
40 let handle = document
43 .as_ref()
44 .and_then(didbot_identity::DidDocument::handle)
45 .filter(|handle| state.registry.handle_did(handle).as_deref() == Some(did))
46 .unwrap_or(INVALID_HANDLE);
47 let mut body = json!({ "did": did, "handle": handle });
48 if let Some(document) = &document {
49 body["didDoc"] = serde_json::to_value(document).map_err(|error| {
50 ApiError::new(
51 StatusCode::INTERNAL_SERVER_ERROR,
52 "DidDocumentUnavailable",
53 error.to_string(),
54 )
55 })?;
56 }
57 let status = account.sync_status();
58 body["active"] = json!(status.is_some_and(|status| status.active));
59 if let Some(reason) = status.and_then(|status| status.status) {
60 body["status"] = json!(reason.as_str());
61 }
62 debug!(did, handle, "answered getSession");
63 Ok(body)
64}