whatsapp_rust/features/
tctoken.rs1use crate::client::Client;
16use crate::request::IqError;
17use wacore::iq::tctoken::{IssuePrivacyTokensSpec, ReceivedTcToken, tc_token_expiration_cutoff};
18use wacore::store::traits::TcTokenEntry;
19use wacore_binary::jid::Jid;
20
21pub struct TcToken<'a> {
23 client: &'a Client,
24}
25
26impl<'a> TcToken<'a> {
27 pub(crate) fn new(client: &'a Client) -> Self {
28 Self { client }
29 }
30
31 pub async fn issue_tokens(&self, jids: &[Jid]) -> Result<Vec<ReceivedTcToken>, IqError> {
36 if jids.is_empty() {
37 return Ok(Vec::new());
38 }
39
40 let spec = IssuePrivacyTokensSpec::new(jids);
41 let response = self.client.execute(spec).await?;
42 let backend = self.client.persistence_manager.backend();
43 let now = std::time::SystemTime::now()
44 .duration_since(std::time::UNIX_EPOCH)
45 .unwrap_or_default()
46 .as_secs() as i64;
47
48 for received in &response.tokens {
49 let entry = TcTokenEntry {
50 token: received.token.clone(),
51 token_timestamp: received.timestamp,
52 sender_timestamp: Some(now),
53 };
54
55 if let Err(e) = backend.put_tc_token(&received.jid.user, &entry).await {
56 log::warn!(target: "Client/TcToken", "Failed to store issued tc_token for {}: {e}", received.jid);
57 }
58 }
59
60 Ok(response.tokens)
61 }
62
63 pub async fn prune_expired(&self) -> Result<u32, anyhow::Error> {
68 let backend = self.client.persistence_manager.backend();
69 let cutoff = tc_token_expiration_cutoff();
70 let deleted = backend.delete_expired_tc_tokens(cutoff).await?;
71
72 if deleted > 0 {
73 log::info!(target: "Client/TcToken", "Pruned {} expired tc_tokens", deleted);
74 }
75
76 Ok(deleted)
77 }
78
79 pub async fn get(&self, jid: &str) -> Result<Option<TcTokenEntry>, anyhow::Error> {
81 let backend = self.client.persistence_manager.backend();
82 Ok(backend.get_tc_token(jid).await?)
83 }
84
85 pub async fn get_all_jids(&self) -> Result<Vec<String>, anyhow::Error> {
87 let backend = self.client.persistence_manager.backend();
88 Ok(backend.get_all_tc_token_jids().await?)
89 }
90}
91
92impl Client {
93 pub fn tc_token(&self) -> TcToken<'_> {
95 TcToken::new(self)
96 }
97}