using EFCDesk.Classes; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Security.Cryptography; using System.Net.NetworkInformation; namespace EFCDesk.Utils { public static class Util { private const string CLAVE_MAESTRA = "EFCDesk_MasterKey_2026"; public static bool StringsValidos(params string?[] valores) { return valores != null && valores.All(v => !string.IsNullOrWhiteSpace(v)); } public static bool TieneValor(T? valor) { return valor != null; } public static string ValorSeguro(string? valor, string valorPorDefecto = "") { return string.IsNullOrWhiteSpace(valor) ? valorPorDefecto : valor; } public static bool EsNumeroPositivo(int valor) { return valor > 0; } public static async Task Login(string usuario, string password) { Globales.configJson = ConfiguracionJSON.LoadFromJson(); bool Esvalido = StringsValidos(Globales.configJson.DominioExp); if (!Esvalido) { MessageBox.Show("La configuración del dominio es inválida. Por favor, revise la configuración.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } Esvalido = StringsValidos(usuario, password); if (!Esvalido) { MessageBox.Show("Debe ingresar Usuario y contraseña.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Globales.configJson.UsuarioExp = ""; Globales.configJson.PasswordExp = ""; Globales.configJson.SaveToJson(); return false; } var apiClient = Globales.ApiClientLarge; // Crear diccionario con los datos var loginData = new Dictionary { { "username", usuario}, { "password", password} }; string ApiPostLogin = Globales.configJson.DominioExp + apiClient.EndpointLoginToken(); string respuestaJson = await apiClient.PostJsonWithoutAuthAsync(url: ApiPostLogin, data: loginData); if (!apiClient.IsJson(respuestaJson)) { return false; } if (!apiClient.HasJsonData(respuestaJson)) { return false; } if (JsonHelper.TryParse(respuestaJson, out var root)) { var JsonData = JsonHelper.ToDictionary(root); if (JsonData == null) { return false; } else { if (JsonData.ContainsKey("access")) { Globales.accesToken = JsonData["access"]?.ToString() ?? ""; } if (JsonData.ContainsKey("refresh")) { Globales.refresToken = JsonData["refresh"]?.ToString() ?? ""; } if (JsonData.ContainsKey("detail")) { string detalle = JsonData["detail"]?.ToString() ?? "Detalle desconocido"; MessageBox.Show(detalle, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } if (JsonData.ContainsKey("success")) { bool success = Convert.ToBoolean(JsonData["success"]); if (!success) { string mensaje = JsonData["message"]?.ToString() ?? "Error desconocido"; MessageBox.Show(mensaje, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } if (string.IsNullOrEmpty(Globales.accesToken) || string.IsNullOrEmpty(Globales.refresToken)) { MessageBox.Show("Error al obtener tokens de autenticación. Por favor, revise sus credenciales y la configuración del dominio.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } } } else { return false; } // Falta lógica para procesar la respuesta y devolver true/false según corresponda // Por ahora, simplemente devolvemos true si la respuesta no es nula o vacía return true; } private static string ObtenerMacAddress() { return NetworkInterface.GetAllNetworkInterfaces() .Where(nic => nic.OperationalStatus == OperationalStatus.Up) .Select(nic => nic.GetPhysicalAddress().ToString()) .FirstOrDefault() ?? "S0luc10n3501"; } private static void DerivarClave(string password, string salt, out byte[] key, out byte[] iv) { key = Array.Empty(); iv = Array.Empty(); try { if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Password inválido"); if (string.IsNullOrWhiteSpace(salt)) throw new ArgumentException("Salt inválido"); using var derivador = new Rfc2898DeriveBytes( password, Encoding.UTF8.GetBytes(salt), 100_000, HashAlgorithmName.SHA256); key = derivador.GetBytes(32); // AES-256 iv = derivador.GetBytes(16); // IV } catch (CryptographicException ex) { } catch (Exception ex) { } } public static string Encriptar(string textoPlano, string? password = null, string? saltOpcional = null) { try { if (string.IsNullOrEmpty(textoPlano)) return string.Empty; string salt = saltOpcional ?? ObtenerMacAddress(); string pass = password ?? CLAVE_MAESTRA; DerivarClave(pass, salt, out var key, out var iv); using var aes = Aes.Create(); aes.Key = key; aes.IV = iv; using var encryptor = aes.CreateEncryptor(); byte[] textoBytes = Encoding.UTF8.GetBytes(textoPlano); byte[] textoEncriptado = encryptor.TransformFinalBlock(textoBytes, 0, textoBytes.Length); return Convert.ToBase64String(textoEncriptado); } catch (CryptographicException ex) { return string.Empty; } catch (Exception ex) { return string.Empty; } } public static string Desencriptar(string textoEncriptado, string? password = null, string? saltOpcional = null) { try { if (string.IsNullOrEmpty(textoEncriptado)) return string.Empty; string salt = saltOpcional ?? ObtenerMacAddress(); string pass = password ?? CLAVE_MAESTRA; DerivarClave(pass, salt, out var key, out var iv); using var aes = Aes.Create(); aes.Key = key; aes.IV = iv; using var decryptor = aes.CreateDecryptor(); byte[] textoBytes = Convert.FromBase64String(textoEncriptado); byte[] textoPlano = decryptor.TransformFinalBlock(textoBytes, 0, textoBytes.Length); return Encoding.UTF8.GetString(textoPlano); } catch (FormatException ex) { return string.Empty; } catch (Exception ex) { return string.Empty; } } public static string FolderTemporales() { // Obtiene la ruta raíz de la carpeta temporal del sistema string tempPath = Path.Combine(Path.GetTempPath(), "temp-efc-desk"); if (!Directory.Exists(tempPath)) { Directory.CreateDirectory(tempPath); } return tempPath; } } }