use crate::client::Client;
use crate::request::IqError;
use wacore::iq::tctoken::{IssuePrivacyTokensSpec, ReceivedTcToken, tc_token_expiration_cutoff};
use wacore::store::traits::TcTokenEntry;
use wacore_binary::jid::Jid;
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>, IqError> {
if jids.is_empty() {
return Ok(Vec::new());
}
let spec = IssuePrivacyTokensSpec::new(jids);
let response = self.client.execute(spec).await?;
let backend = self.client.persistence_manager.backend();
let now = wacore::time::now_secs();
for received in &response.tokens {
let entry = TcTokenEntry {
token: received.token.clone(),
token_timestamp: received.timestamp,
sender_timestamp: Some(now),
};
if let Err(e) = backend.put_tc_token(&received.jid.user, &entry).await {
log::warn!(target: "Client/TcToken", "Failed to store issued tc_token for {}: {e}", received.jid);
}
}
Ok(response.tokens)
}
pub async fn prune_expired(&self) -> Result<u32, anyhow::Error> {
let backend = self.client.persistence_manager.backend();
let cutoff = tc_token_expiration_cutoff();
let deleted = backend.delete_expired_tc_tokens(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>, anyhow::Error> {
let backend = self.client.persistence_manager.backend();
Ok(backend.get_tc_token(jid).await?)
}
pub async fn get_all_jids(&self) -> Result<Vec<String>, anyhow::Error> {
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)
}
}