use crate::client::Client;
use crate::request::IqError;
use crate::store::error::StoreError;
use thiserror::Error;
use wacore::iq::tctoken::{IssuePrivacyTokensSpec, ReceivedTcToken};
use wacore::store::traits::TcTokenEntry;
use wacore_binary::Jid;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum TcTokenError {
#[error("{0}")]
Iq(#[from] IqError),
#[error("{0}")]
Store(#[from] StoreError),
}
pub struct TcToken<'a> {
client: &'a Client,
}
impl<'a> TcToken<'a> {
pub(crate) fn new(client: &'a Client) -> Self {
Self { client }
}
pub async fn issue_tokens(&self, jids: &[Jid]) -> Result<Vec<ReceivedTcToken>, TcTokenError> {
if jids.is_empty() {
return Ok(Vec::new());
}
let spec = IssuePrivacyTokensSpec::new(jids);
let response = self.client.execute(spec).await?;
self.client.store_issued_tc_tokens(&response.tokens).await;
Ok(response.tokens)
}
pub async fn prune_expired(&self) -> Result<u32, TcTokenError> {
use wacore::iq::tctoken::{
sender_tc_token_expiration_cutoff_with, tc_token_expiration_cutoff_with,
};
let backend = self.client.persistence_manager.backend();
let tc_config = self.client.tc_token_config().await;
let token_cutoff = tc_token_expiration_cutoff_with(&tc_config);
let sender_cutoff = sender_tc_token_expiration_cutoff_with(&tc_config);
let deleted = backend
.delete_expired_tc_tokens(token_cutoff, sender_cutoff)
.await?;
if deleted > 0 {
log::info!(target: "Client/TcToken", "Pruned {} expired tc_tokens", deleted);
}
Ok(deleted)
}
pub async fn get(&self, jid: &str) -> Result<Option<TcTokenEntry>, TcTokenError> {
let backend = self.client.persistence_manager.backend();
Ok(backend.get_tc_token(jid).await?)
}
pub async fn get_all_jids(&self) -> Result<Vec<String>, TcTokenError> {
let backend = self.client.persistence_manager.backend();
Ok(backend.get_all_tc_token_jids().await?)
}
}
impl Client {
pub fn tc_token(&self) -> TcToken<'_> {
TcToken::new(self)
}
}