ddnet_account_client/
logout_all.rs

1use ddnet_accounts_shared::client::{logout_all, machine_id::machine_uid};
2use thiserror::Error;
3
4use crate::{
5    errors::{FsLikeError, HttpLikeError},
6    interface::Io,
7    safe_interface::{IoSafe, SafeIo},
8};
9
10/// The result of a [`logout_all`] request.
11#[derive(Error, Debug)]
12pub enum LogoutAllResult {
13    /// A http like error occurred.
14    #[error("{0}")]
15    HttpLikeError(HttpLikeError),
16    /// A fs like error occurred.
17    #[error("{0}")]
18    FsLikeError(FsLikeError),
19    /// Errors that are not handled explicitly.
20    #[error("Delete failed: {0}")]
21    Other(anyhow::Error),
22}
23
24impl From<HttpLikeError> for LogoutAllResult {
25    fn from(value: HttpLikeError) -> Self {
26        Self::HttpLikeError(value)
27    }
28}
29
30impl From<FsLikeError> for LogoutAllResult {
31    fn from(value: FsLikeError) -> Self {
32        Self::FsLikeError(value)
33    }
34}
35
36/// Delete all sessions of an account on the account server, except
37/// for the current one.
38pub async fn logout_all(
39    account_token_hex: String,
40    io: &dyn Io,
41) -> anyhow::Result<(), LogoutAllResult> {
42    logout_all_impl(account_token_hex, io.into()).await
43}
44
45async fn logout_all_impl(
46    account_token_hex: String,
47    io: IoSafe<'_>,
48) -> anyhow::Result<(), LogoutAllResult> {
49    // read session's key-pair
50    let key_pair = io.read_serialized_session_key_pair().await?;
51
52    let hashed_hw_id = machine_uid().map_err(LogoutAllResult::Other)?;
53
54    let delete_req = logout_all::logout_all(
55        account_token_hex,
56        hashed_hw_id,
57        &key_pair.private_key,
58        key_pair.public_key,
59    )
60    .map_err(LogoutAllResult::Other)?;
61
62    io.request_logout_all(delete_req)
63        .await?
64        .map_err(|err| LogoutAllResult::Other(err.into()))?;
65
66    Ok(())
67}