using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using Newtonsoft.Json; namespace Azaion.LoaderUI; public interface IAzaionApi { void Login(ApiCredentials credentials); Task GetLastInstallerName(string folder); Task<(string name, Stream stream)> DownloadInstaller(string folder); } public class AzaionApi(HttpClient client) : IAzaionApi { private string _jwtToken = null!; const string APP_JSON = "application/json"; private ApiCredentials _credentials = null!; public void Login(ApiCredentials credentials) { _credentials = credentials; } public async Task GetLastInstallerName(string folder) { var res = await Get>($"/resources/list/{folder}"); return res?.FirstOrDefault() ?? ""; } public async Task<(string name, Stream stream)> DownloadInstaller(string folder) { var response = await Send(new HttpRequestMessage(HttpMethod.Get, $"resources/get-installer/{folder}")); var fileStream = await response.Content.ReadAsStreamAsync(); var fileName = response.Content.Headers.ContentDisposition?.FileName?.Trim('"') ?? "installer.exe"; return (fileName, fileStream); } private async Task Send(HttpRequestMessage request) { if (string.IsNullOrEmpty(_jwtToken)) await Authorize(); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _jwtToken); var response = await client.SendAsync(request); if (response.StatusCode == HttpStatusCode.Unauthorized) { await Authorize(); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _jwtToken); response = await client.SendAsync(request); } if (response.IsSuccessStatusCode) return response; var stream = await response.Content.ReadAsStreamAsync(); var content = await new StreamReader(stream).ReadToEndAsync(); if (response.StatusCode == HttpStatusCode.Conflict) { var result = JsonConvert.DeserializeObject(content); throw new Exception($"Failed: {response.StatusCode}! Error Code: {result?.ErrorCode}. Message: {result?.Message}"); } throw new Exception($"Failed: {response.StatusCode}! Result: {content}"); } private async Task Get(string url) { var response = await Send(new HttpRequestMessage(HttpMethod.Get, url)); var stream = await response.Content.ReadAsStreamAsync(); var json = await new StreamReader(stream).ReadToEndAsync(); return JsonConvert.DeserializeObject(json); } private async Task Put(string url, T obj) { await Send(new HttpRequestMessage(HttpMethod.Put, url) { Content = new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, APP_JSON) }); } private async Task Authorize() { try { if (string.IsNullOrEmpty(_credentials.Email) || _credentials.Password.Length == 0) throw new Exception("Email or password is empty! Please do EnterCredentials first!"); var content = new StringContent(JsonConvert.SerializeObject(new { email = _credentials.Email, password = _credentials.Password }), Encoding.UTF8, APP_JSON); var message = new HttpRequestMessage(HttpMethod.Post, "login") { Content = content }; var response = await client.SendAsync(message); if (!response.IsSuccessStatusCode) throw new Exception($"EnterCredentials failed: {response.StatusCode}"); var stream = await response.Content.ReadAsStreamAsync(); var json = await new StreamReader(stream).ReadToEndAsync(); var result = JsonConvert.DeserializeObject(json); if (string.IsNullOrEmpty(result?.Token)) throw new Exception("JWT Token not found in response"); _jwtToken = result.Token; } catch (Exception e) { Console.WriteLine(e); throw; } } }