+75
-2
crates/atproto-client/src/com_atproto_server.rs
+75
-2
crates/atproto-client/src/com_atproto_server.rs
···
1
1
//! AT Protocol server authentication operations.
2
2
//!
3
3
//! Client functions for com.atproto.server XRPC methods including
4
-
//! session creation and refresh with app password authentication.
4
+
//! session creation, refresh, and deletion with app password authentication.
5
5
//! - **`create_app_password()`**: Create a new app password for authenticated account
6
+
//! - **`delete_session()`**: Delete the current authentication session
6
7
//!
7
8
//! ## Request/Response Types
8
9
//!
···
21
22
use atproto_identity::url::URLBuilder;
22
23
use serde::{Deserialize, Serialize};
23
24
24
-
use crate::client::post_json;
25
+
use crate::{
26
+
client::{Auth, post_json},
27
+
errors::ClientError,
28
+
};
25
29
26
30
/// Request to create a new authentication session.
27
31
#[cfg_attr(debug_assertions, derive(Debug))]
···
219
223
220
224
serde_json::from_value(value).map_err(|err| err.into())
221
225
}
226
+
227
+
/// Deletes the current authentication session.
228
+
///
229
+
/// Terminates the authenticated session, invalidating the current access token.
230
+
/// This operation requires app password authentication and will fail with
231
+
/// other authentication methods.
232
+
///
233
+
/// # Arguments
234
+
///
235
+
/// * `http_client` - HTTP client for making requests
236
+
/// * `auth` - Authentication method (must be AppPassword)
237
+
/// * `base_url` - Base URL of the AT Protocol server
238
+
///
239
+
/// # Returns
240
+
///
241
+
/// Returns `Ok(())` on successful session deletion (HTTP 200 response)
242
+
///
243
+
/// # Errors
244
+
///
245
+
/// Returns `ClientError::InvalidAuthMethod` if authentication is not AppPassword,
246
+
/// or other errors for HTTP request failures.
247
+
pub async fn delete_session(
248
+
http_client: &reqwest::Client,
249
+
auth: &Auth,
250
+
base_url: &str,
251
+
) -> Result<()> {
252
+
// Ensure we have AppPassword authentication
253
+
let app_auth = match auth {
254
+
Auth::AppPassword(app_auth) => app_auth,
255
+
_ => {
256
+
return Err(ClientError::InvalidAuthMethod {
257
+
method: "deleteSession requires AppPassword authentication".to_string(),
258
+
}
259
+
.into());
260
+
}
261
+
};
262
+
263
+
let mut url_builder = URLBuilder::new(base_url);
264
+
url_builder.path("/xrpc/com.atproto.server.deleteSession");
265
+
let url = url_builder.build();
266
+
267
+
// Create headers with the Bearer token
268
+
let mut headers = reqwest::header::HeaderMap::new();
269
+
headers.insert(
270
+
reqwest::header::AUTHORIZATION,
271
+
reqwest::header::HeaderValue::from_str(&format!("Bearer {}", app_auth.access_token))?,
272
+
);
273
+
274
+
// Send POST request with no body
275
+
let response = http_client
276
+
.post(&url)
277
+
.headers(headers)
278
+
.send()
279
+
.await
280
+
.map_err(|error| ClientError::HttpRequestFailed {
281
+
url: url.clone(),
282
+
error,
283
+
})?;
284
+
285
+
// Check for successful response (200 OK)
286
+
if response.status() == reqwest::StatusCode::OK {
287
+
Ok(())
288
+
} else {
289
+
Err(anyhow::anyhow!(
290
+
"deleteSession failed: expected 200 OK, got {}",
291
+
response.status()
292
+
))
293
+
}
294
+
}
+7
crates/atproto-client/src/errors.rs
+7
crates/atproto-client/src/errors.rs
···
85
85
/// The underlying streaming error
86
86
error: reqwest::Error,
87
87
},
88
+
89
+
/// Occurs when an invalid authentication method is used for an operation
90
+
#[error("error-atproto-client-http-4 Invalid authentication method: {method}")]
91
+
InvalidAuthMethod {
92
+
/// Description of the authentication requirement
93
+
method: String,
94
+
},
88
95
}
89
96
90
97
/// Error types that can occur during DPoP authentication operations.