using DeluxeBackend.Models; using System.Net.Http.Headers; using System.Numerics; using System.Security.Claims; using System.Security.Cryptography; using System.Text; namespace DeluxeBackend.Services { public interface ICdnService { Task UploadFile(Stream fileStream, string filePath); Task UploadFile(Stream fileStream, string filePath, string fileName); Task<(string? Url, string? Proof)> UploadFile(Stream fileStream, string filePath, Account account); } public class CdnService(HttpClient httpClient) : ICdnService { public static readonly string Url = "http://127.0.0.1:9823/"; private static readonly string apiUrl = "http://127.0.0.1:9823/api/internal/v1/upload"; private readonly string apiKey = "KittyRec_6767_1b9b24fe-eb5a-486b-af29-dba01b8de861"; private static readonly string proofSecret = "SUPER_SECRET_OWNERSHIP_SIGNING_KEY_12345"; public async Task UploadFile(Stream fileStream, string filePath) { try { using var request = new HttpRequestMessage(HttpMethod.Post, apiUrl); request.Headers.Add("X-API-KEY", apiKey); var content = new MultipartFormDataContent(); var fileContent = new StreamContent(fileStream); fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); content.Add(fileContent, "file", "data.bin"); content.Add(new StringContent(filePath), "type"); request.Content = content; var response = await httpClient.SendAsync(request); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsStringAsync(); } return null; } catch (Exception ex) { Console.WriteLine($"Upload failed: {ex.Message}"); return null; } } internal static string GenerateOwnershipProof(Account account, string fileName) { var payload = $"{Environment.MachineName}:{account.Id}:{account.CreatedAt.Ticks}:{fileName}"; using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(proofSecret)); var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload)); return Convert.ToBase64String(hash); } public async Task UploadFile(Stream fileStream, string filePath, string fileName) { try { using var request = new HttpRequestMessage(HttpMethod.Post, apiUrl); request.Headers.Add("X-API-KEY", apiKey); var content = new MultipartFormDataContent(); var fileContent = new StreamContent(fileStream); fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); content.Add(fileContent, "file", "data.bin"); content.Add(new StringContent(filePath), "type"); content.Add(new StringContent(fileName), "filename"); request.Content = content; var response = await httpClient.SendAsync(request); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsStringAsync(); } return null; } catch (Exception ex) { Console.WriteLine($"Upload failed: {ex.Message}"); return null; } } public async Task<(string? Url, string? Proof)> UploadFile(Stream fileStream, string filePath, Account account) { try { using var request = new HttpRequestMessage(HttpMethod.Post, apiUrl); request.Headers.Add("X-API-KEY", apiKey); var content = new MultipartFormDataContent(); var fileContent = new StreamContent(fileStream); fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); content.Add(fileContent, "file", "data.bin"); content.Add(new StringContent(filePath), "type"); request.Content = content; var response = await httpClient.SendAsync(request); if (response.IsSuccessStatusCode) { if (response.IsSuccessStatusCode) { string fileName = await response.Content.ReadAsStringAsync(); string proof = GenerateOwnershipProof(account, fileName); return (fileName, proof); } } return (null, null); } catch (Exception ex) { Console.WriteLine($"Upload failed: {ex.Message}"); return (null, null); } } } }