| 1 | use crate::{ |
| 2 | command::constants::{ |
| 3 | base_url_builder, PATH_ACCOUNT_LOGIN, PATH_ACCOUNT_LOGOUT, PATH_ACCOUNT_PROFILE, |
| 4 | PATH_ACCOUNT_REGISTER, |
| 5 | }, |
| 6 | models::{ |
| 7 | account::{ |
| 8 | AccountLoginResponse, AccountProfileResponse, AccountRegisterResponse, ErrorResponse, |
| 9 | LoginResponse, ProfileResponse, RegisterResponse, |
| 10 | }, |
| 11 | player::TauriResponse, |
| 12 | }, |
| 13 | rest::parse_error_response, |
| 14 | }; |
| 15 | use crate_error_codes::ErrorCode; |
| 16 | use log::{debug, error}; |
| 17 | use reqwest::Client; |
| 18 | use serde_json::json; |
| 19 | use tauri; |
| 20 | |
| 21 | #[tauri::command] |
| 22 | pub async fn account_login( |
| 23 | username: String, |
| 24 | password: String, |
| 25 | ) -> Result<AccountLoginResponse, ErrorResponse> { |
| 26 | debug!( |
| 27 | "Logging in with username {}, password {}", |
| 28 | username, password |
| 29 | ); |
| 30 | // Login |
| 31 | let body = json!( { |
| 32 | "username": username, |
| 33 | "password": password |
| 34 | }); |
| 35 | let result = Client::new() |
| 36 | .post(account_url_builder(PATH_ACCOUNT_LOGIN)) |
| 37 | .json(&body) |
| 38 | .send() |
| 39 | .await; |
| 40 | |
| 41 | let response = match result { |
| 42 | Ok(ok_response) => ok_response, |
| 43 | Err(e) => { |
| 44 | error!("Failed to get response: {:?}", e); |
| 45 | return Err(ErrorResponse { |
| 46 | error_code: ErrorCode::NetworkError, |
| 47 | message: ErrorCode::NetworkError.error_message().to_string(), |
| 48 | }); |
| 49 | } |
| 50 | }; |
| 51 | |
| 52 | let ok_response = match response.status() { |
| 53 | reqwest::StatusCode::OK => response, |
| 54 | _ => { |
| 55 | error!("Failed to login: {:?}", response); |
| 56 | let error_response = parse_error_response(response).await; |
| 57 | return error_response; |
| 58 | } |
| 59 | }; |
| 60 | |
| 61 | let token = match ok_response.headers().get("Authorization") { |
| 62 | Some(token) => { |
| 63 | // Trim Bearer prefix |
| 64 | let token = match token.to_str() { |
| 65 | Ok(token) => token.trim_start_matches("Bearer "), |
| 66 | Err(e) => { |
| 67 | error!("Cannot convert token to str: {:?}", e); |
| 68 | return Err(ErrorResponse { |
| 69 | error_code: ErrorCode::ParseError, |
| 70 | message: ErrorCode::ParseError.error_message().to_string(), |
| 71 | }); |
| 72 | } |
| 73 | }; |
| 74 | Some(token.to_string()) |
| 75 | } |
| 76 | None => { |
| 77 | error!("No Authorization header found."); |
| 78 | return Err(ErrorResponse { |
| 79 | error_code: ErrorCode::ParseError, |
| 80 | message: ErrorCode::ParseError.error_message().to_string(), |
| 81 | }); |
| 82 | } |
| 83 | }; |
| 84 | debug!("Token: {:?}", token); |
| 85 | let res: LoginResponse = match ok_response.json().await { |
| 86 | Ok(json) => json, |
| 87 | Err(e) => { |
| 88 | error!("Failed to parse response: {:?}", e); |
| 89 | return Err(ErrorResponse { |
| 90 | error_code: ErrorCode::ParseError, |
| 91 | message: ErrorCode::ParseError.error_message().to_string(), |
| 92 | }); |
| 93 | } |
| 94 | }; |
| 95 | debug!("Login response: {:?}", res); |
| 96 | Ok(AccountLoginResponse { |
| 97 | status: TauriResponse::Success, |
| 98 | message: res.message, |
| 99 | access_token: token, |
| 100 | user: res.user, |
| 101 | }) |
| 102 | } |
| 103 | |
| 104 | #[tauri::command] |
| 105 | pub async fn account_logout(access_token: String) { |
| 106 | debug!("Logging out with access token {}", access_token); |
| 107 | // Logout |
| 108 | let response = Client::new() |
| 109 | .delete(account_url_builder(PATH_ACCOUNT_LOGOUT)) |
| 110 | .header("Authorization", format!("Bearer {}", access_token)) |
| 111 | .send() |
| 112 | .await; |
| 113 | |
| 114 | match response { |
| 115 | Ok(response) => { |
| 116 | debug!("Got response: {:?}", response); |
| 117 | } |
| 118 | Err(e) => { |
| 119 | println!("Failed to get response: {:?}", e); |
| 120 | } |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | #[tauri::command] |
| 125 | pub async fn account_register( |
| 126 | name: String, |
| 127 | email: String, |
| 128 | password: String, |
| 129 | ) -> AccountRegisterResponse { |
| 130 | debug!("Registering with name {} and email {}.", name, email); |
| 131 | // Register |
| 132 | let body = json!( { |
| 133 | "name": name, |
| 134 | "email": email, |
| 135 | "password": password |
| 136 | }); |
| 137 | let response = Client::new() |
| 138 | .post(account_url_builder(PATH_ACCOUNT_REGISTER)) |
| 139 | .json(&body) |
| 140 | .send() |
| 141 | .await; |
| 142 | |
| 143 | match response { |
| 144 | Ok(response) => { |
| 145 | debug!("Got response: {:?}", response); |
| 146 | let res: RegisterResponse = match response.json().await { |
| 147 | Ok(json) => json, |
| 148 | Err(e) => { |
| 149 | println!("Failed to parse response: {:?}", e); |
| 150 | return AccountRegisterResponse { |
| 151 | status: TauriResponse::Error, |
| 152 | message: e.to_string(), |
| 153 | user: None, |
| 154 | }; |
| 155 | } |
| 156 | }; |
| 157 | debug!("Register response: {:?}", res); |
| 158 | AccountRegisterResponse { |
| 159 | status: TauriResponse::Success, |
| 160 | message: res.message, |
| 161 | user: res.user, |
| 162 | } |
| 163 | } |
| 164 | Err(e) => { |
| 165 | println!("Failed to get response: {:?}", e); |
| 166 | AccountRegisterResponse { |
| 167 | status: TauriResponse::Error, |
| 168 | message: e.to_string(), |
| 169 | user: None, |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | #[tauri::command] |
| 176 | pub async fn account_profile(user_id: String) -> AccountProfileResponse { |
| 177 | debug!("Getting profile for user_id {}", user_id); |
| 178 | // Get profile |
| 179 | let url = account_url_builder(PATH_ACCOUNT_PROFILE).replace("{userId}", &user_id); |
| 180 | let response = Client::new().get(&url).send().await; |
| 181 | |
| 182 | let response = match response { |
| 183 | Ok(response) => response, |
| 184 | Err(e) => { |
| 185 | debug!("Failed to get response: {:?}", e); |
| 186 | return AccountProfileResponse { |
| 187 | status: TauriResponse::Error, |
| 188 | message: e.to_string(), |
| 189 | user: None, |
| 190 | }; |
| 191 | } |
| 192 | }; |
| 193 | let res: ProfileResponse = match response.json().await { |
| 194 | Ok(json) => json, |
| 195 | Err(e) => { |
| 196 | debug!("Failed to parse response: {:?}", e); |
| 197 | return AccountProfileResponse { |
| 198 | status: TauriResponse::Error, |
| 199 | message: e.to_string(), |
| 200 | user: None, |
| 201 | }; |
| 202 | } |
| 203 | }; |
| 204 | debug!("Profile response: {:?}", res); |
| 205 | AccountProfileResponse { |
| 206 | status: TauriResponse::Success, |
| 207 | message: res.message, |
| 208 | user: res.user, |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | fn account_url_builder(path: &str) -> String { |
| 213 | let mut base_url = base_url_builder(); |
| 214 | base_url.add_route(path); |
| 215 | base_url.build() |
| 216 | } |