talk_api_internal/auth/
mod.rs

1pub 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 server_time: u64,
36
37    // #[serde(rename = "resetUserData")]
38    // pub reset_user_data: bool,
39    // pub story_url: Option<String>,
40    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}