libsignal_service/push_service/
account.rs1use std::fmt;
2
3use chrono::{DateTime, Utc};
4use phonenumber::PhoneNumber;
5use reqwest::Method;
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9use super::{
10 response::ReqwestExt, HttpAuthOverride, PushService, ServiceError,
11};
12use crate::{
13 configuration::Endpoint,
14 utils::{serde_optional_base64, serde_phone_number},
15};
16
17#[derive(Debug, Serialize, Deserialize, Clone)]
18pub struct ServiceIds {
19 #[serde(rename = "uuid")]
20 pub aci: Uuid,
21 #[serde(default)] pub pni: Uuid,
23}
24
25impl ServiceIds {
26 pub fn aci(&self) -> libsignal_protocol::Aci {
27 libsignal_protocol::Aci::from_uuid_bytes(self.aci.into_bytes())
28 }
29
30 pub fn pni(&self) -> libsignal_protocol::Pni {
31 libsignal_protocol::Pni::from_uuid_bytes(self.pni.into_bytes())
32 }
33}
34
35impl fmt::Display for ServiceIds {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 write!(f, "aci={} pni={}", self.aci, self.pni)
38 }
39}
40
41#[derive(Debug, Serialize, Deserialize)]
42#[serde(rename_all = "camelCase")]
43pub struct DeviceId {
44 pub device_id: u32,
45}
46
47#[derive(Debug, Serialize, Deserialize)]
48#[serde(rename_all = "camelCase")]
49pub struct DeviceInfo {
50 pub id: i64,
51 pub name: Option<String>,
52 #[serde(with = "chrono::serde::ts_milliseconds")]
53 pub created: DateTime<Utc>,
54 #[serde(with = "chrono::serde::ts_milliseconds")]
55 pub last_seen: DateTime<Utc>,
56}
57
58#[derive(Debug, Serialize, Deserialize)]
59#[serde(rename_all = "camelCase")]
60pub struct AccountAttributes {
61 #[serde(default, with = "serde_optional_base64")]
62 pub signaling_key: Option<Vec<u8>>,
63 pub registration_id: u32,
64 pub pni_registration_id: u32,
65 pub voice: bool,
66 pub video: bool,
67 pub fetches_messages: bool,
68 pub pin: Option<String>,
69 pub registration_lock: Option<String>,
70 #[serde(default, with = "serde_optional_base64")]
71 pub unidentified_access_key: Option<Vec<u8>>,
72 pub unrestricted_unidentified_access: bool,
73 pub discoverable_by_phone_number: bool,
74 pub capabilities: DeviceCapabilities,
75 pub name: Option<String>,
76}
77
78#[derive(Debug, Serialize, Deserialize, Default, Eq, PartialEq, Clone)]
79#[serde(rename_all = "camelCase")]
80pub struct DeviceCapabilities {
81 #[serde(default)]
82 pub storage: bool,
83 #[serde(default)]
84 pub sender_key: bool,
85 #[serde(default)]
86 pub announcement_group: bool,
87 #[serde(default)]
88 pub change_number: bool,
89 #[serde(default)]
90 pub stories: bool,
91 #[serde(default)]
92 pub gift_badges: bool,
93 #[serde(default)]
94 pub pni: bool,
95 #[serde(default)]
96 pub payment_activation: bool,
97}
98
99#[derive(Debug, Deserialize)]
100#[serde(rename_all = "camelCase")]
101pub struct WhoAmIResponse {
102 #[serde(rename = "uuid")]
103 pub aci: Uuid,
104 #[serde(default)] pub pni: Uuid,
106 #[serde(with = "serde_phone_number")]
107 pub number: PhoneNumber,
108}
109
110impl PushService {
111 pub async fn whoami(&mut self) -> Result<WhoAmIResponse, ServiceError> {
113 self.request(
114 Method::GET,
115 Endpoint::service("/v1/accounts/whoami"),
116 HttpAuthOverride::NoOverride,
117 )?
118 .send()
119 .await?
120 .service_error_for_status()
121 .await?
122 .json()
123 .await
124 .map_err(Into::into)
125 }
126
127 pub async fn devices(&mut self) -> Result<Vec<DeviceInfo>, ServiceError> {
131 #[derive(serde::Deserialize)]
132 struct DeviceInfoList {
133 devices: Vec<DeviceInfo>,
134 }
135
136 let devices: DeviceInfoList = self
137 .request(
138 Method::GET,
139 Endpoint::service("/v1/devices/"),
140 HttpAuthOverride::NoOverride,
141 )?
142 .send()
143 .await?
144 .service_error_for_status()
145 .await?
146 .json()
147 .await?;
148
149 Ok(devices.devices)
150 }
151
152 pub async fn set_account_attributes(
153 &mut self,
154 attributes: AccountAttributes,
155 ) -> Result<(), ServiceError> {
156 assert!(
157 attributes.pin.is_none() || attributes.registration_lock.is_none(),
158 "only one of PIN and registration lock can be set."
159 );
160
161 self.request(
162 Method::PUT,
163 Endpoint::service("/v1/accounts/attributes/"),
164 HttpAuthOverride::NoOverride,
165 )?
166 .json(&attributes)
167 .send()
168 .await?
169 .service_error_for_status()
170 .await?
171 .json()
172 .await
173 .map_err(Into::into)
174 }
175}