talk_api_internal/auth/
mod.rs1pub mod client;
2pub mod status;
3pub mod xvc;
4
5use reqwest::Method;
6
7use crate::{read_response, read_structured_response, ApiResult};
8
9use self::{
10 client::{AuthClient, Device},
11 xvc::XvcHasher,
12};
13
14use serde::{Deserialize, Serialize};
15
16#[derive(Debug, Clone, Copy, Serialize)]
17pub struct AccountForm<'a> {
18 pub email: &'a str,
19 pub password: &'a str,
20}
21
22#[derive(Debug, Clone, Deserialize)]
23pub struct Login {
24 #[serde(rename = "userId")]
25 pub user_id: u64,
26
27 #[serde(rename = "countryIso")]
28 pub country_iso: String,
29 #[serde(rename = "countryCode")]
30 pub country_code: String,
31
32 #[serde(rename = "accountId")]
33 pub account_id: u64,
34
35 pub access_token: String,
41 pub refresh_token: String,
42 pub token_type: String,
43
44 #[serde(rename = "autoLoginAccountId")]
45 pub auto_login_account_id: String,
46 #[serde(rename = "displayAccountId")]
47 pub display_account_id: String,
48
49 #[serde(rename = "mainDeviceAgentName")]
50 pub main_device_agent_name: String,
51 #[serde(rename = "mainDeviceAppVersion")]
52 pub main_device_app_version: String,
53}
54
55impl Login {
56 pub async fn request_with_account(
57 client: AuthClient<'_, impl XvcHasher>,
58 account: AccountForm<'_>,
59 forced: bool,
60 ) -> ApiResult<Self> {
61 #[derive(Serialize)]
62 struct Form<'a> {
63 #[serde(flatten)]
64 device: Device<'a>,
65
66 #[serde(flatten)]
67 account: AccountForm<'a>,
68 forced: bool,
69 }
70
71 let form = Form {
72 device: client.device,
73 account,
74 forced,
75 };
76
77 read_structured_response(
78 client
79 .request(Method::POST, "account/login.json", account.email)?
80 .form(&form),
81 )
82 .await
83 }
84
85 pub async fn request_with_token(
86 client: AuthClient<'_, impl XvcHasher>,
87 email: &str,
88 token: &str,
89 forced: bool,
90 locked: bool,
91 ) -> ApiResult<Self> {
92 #[derive(Serialize)]
93 struct Form<'a> {
94 #[serde(flatten)]
95 device: Device<'a>,
96
97 email: &'a str,
98 password: &'a str,
99 auto_login: bool,
100 autowithlock: bool,
101 forced: bool,
102 }
103
104 let form = Form {
105 device: client.device,
106 email,
107 password: token,
108 auto_login: true,
109 autowithlock: locked,
110 forced,
111 };
112
113 read_structured_response(
114 client
115 .request(Method::POST, "account/login.json", email)?
116 .form(&form),
117 )
118 .await
119 }
120}
121
122pub async fn request_passcode(
123 client: AuthClient<'_, impl XvcHasher>,
124 account: AccountForm<'_>,
125) -> ApiResult<()> {
126 #[derive(Serialize)]
127 struct Form<'a> {
128 #[serde(flatten)]
129 device: Device<'a>,
130
131 #[serde(flatten)]
132 account: AccountForm<'a>,
133 }
134
135 let form = Form {
136 device: client.device,
137 account,
138 };
139
140 read_response(
141 client
142 .request(Method::POST, "account/request_passcode.json", account.email)?
143 .form(&form),
144 )
145 .await?;
146
147 Ok(())
148}
149
150pub async fn register_device(
151 client: AuthClient<'_, impl XvcHasher>,
152 account: AccountForm<'_>,
153 passcode: &str,
154 permanent: bool,
155) -> ApiResult<()> {
156 #[derive(Serialize)]
157 struct Form<'a> {
158 #[serde(flatten)]
159 device: Device<'a>,
160
161 #[serde(flatten)]
162 account: AccountForm<'a>,
163
164 passcode: &'a str,
165 permanent: bool,
166 }
167
168 let form = Form {
169 device: client.device,
170 account,
171 passcode,
172 permanent,
173 };
174
175 read_response(
176 client
177 .request(Method::POST, "account/register_device.json", account.email)?
178 .form(&form),
179 )
180 .await?;
181
182 Ok(())
183}