1use serde::{Deserialize, Serialize};
2use reqwest::Client;
3use std::error::Error;
4
5#[derive(Serialize, Deserialize)]
6pub struct LoginRequest {
7 pub username: String,
8 pub password: String,
9 pub hwid: String,
10}
11
12pub struct LicenseAPI {
13 url: String,
14 client: Client,
15}
16
17impl LicenseAPI {
18 pub fn new(url: impl Into<String>) -> Self {
19 LicenseAPI {
20 url: url.into(),
21 client: Client::new(),
22 }
23 }
24
25 pub async fn login(&self, creds: &LoginRequest) -> Result<bool, Box<dyn Error + Send + Sync>> {
26 let login_resp = self
27 .client
28 .post(&format!("{}/auth/login", self.url.trim_end_matches('/')))
29 .form(creds)
30 .send()
31 .await?
32 .error_for_status()?;
33
34 let access_token: String = login_resp
35 .json::<serde_json::Value>()
36 .await?
37 .get("access_token")
38 .and_then(|v| v.as_str().map(String::from))
39 .ok_or("missing access_token in response")?;
40
41 let _ = self
42 .client
43 .patch(&format!("{}/users/hwid", self.url.trim_end_matches('/')))
44 .bearer_auth(&access_token)
45 .json(&serde_json::json!({ "hwid": creds.hwid }))
46 .send()
47 .await?
48 .error_for_status()?;
49
50 Ok(true)
51 }
52}