using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using Application.Helpers; using Infrastructure; using Microsoft.EntityFrameworkCore; using MongoDB.Driver; using Newtonsoft.Json.Linq; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.OpenSsl; namespace API; public static class StartupHelper { public static X509Certificate2 LoadCertificateWithKey(string certPath, string keyPath) { var cert = new X509Certificate2(certPath); AsymmetricKeyParameter key; using (var reader = File.OpenText(keyPath)) { var pemReader = new PemReader(reader); key = (AsymmetricKeyParameter)pemReader.ReadObject(); } if (key is not RsaPrivateCrtKeyParameters rsaKey) throw new ArgumentException("Unsupported key type"); var rsa = RSA.Create(); rsa.ImportParameters(new RSAParameters { Modulus = rsaKey.Modulus.ToByteArrayUnsigned(), Exponent = rsaKey.PublicExponent.ToByteArrayUnsigned(), D = rsaKey.Exponent.ToByteArrayUnsigned(), P = rsaKey.P.ToByteArrayUnsigned(), Q = rsaKey.Q.ToByteArrayUnsigned(), DP = rsaKey.DP.ToByteArrayUnsigned(), DQ = rsaKey.DQ.ToByteArrayUnsigned(), InverseQ = rsaKey.QInv.ToByteArrayUnsigned() }); return cert.CopyWithPrivateKey(rsa); } public static void EnsureSslCertificate() { var certPath = "certs"; // Directory to store certificates Directory.CreateDirectory(certPath); // Ensure the directory exists var certFile = Path.Combine(certPath, "server.crt"); var keyFile = Path.Combine(certPath, "server.key"); if (!File.Exists(certFile) || !File.Exists(keyFile)) { Console.WriteLine("Generating SSL certificate..."); // Command to generate a private key and certificate ExecuteCommand( $"openssl req -x509 -newkey rsa:4096 -keyout \"{keyFile}\" -out \"{certFile}\" -days 365 -nodes -subj \"/CN=localhost\""); } else { Console.WriteLine("SSL certificate already exists."); } } private static void ExecuteCommand(string command) { string fileName, arguments; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { fileName = "cmd.exe"; arguments = "/c \"" + command + "\""; } else { fileName = "/bin/bash"; arguments = "-c \"" + command.Replace("\"", "\\\"") + "\""; // Properly escape quotes } var processInfo = new ProcessStartInfo(fileName, arguments) { CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; using (var process = Process.Start(processInfo)) { if (process != null) { process.WaitForExit(); var output = process.StandardOutput.ReadToEnd(); var error = process.StandardError.ReadToEnd(); Console.WriteLine("Command executed: " + command); if (!string.IsNullOrEmpty(output)) Console.WriteLine("Output: " + output); if (!string.IsNullOrEmpty(error)) Console.WriteLine("Error: " + error); } } } public static void EnsureKeysGenerated(IConfiguration configuration, string contentRootPath) { var apiKey = configuration["ApiKey"]; var jwtSecretKey = configuration["Jwt:SecretKey"]; var medicalHistoryKey = configuration["MedicalRecordsKey"]; var appSettingsPath = Path.Combine(contentRootPath, "appsettings.json"); var json = JObject.Parse(File.ReadAllText(appSettingsPath)); var modified = false; if (string.IsNullOrEmpty(apiKey)) { var newApiKey = KeyGenerator.GenerateApiKey(); json["ApiKey"] = newApiKey; modified = true; } if (string.IsNullOrEmpty(medicalHistoryKey)) { var newMedicalHistoryKey = KeyGenerator.GenerateApiKey(); json["MedicalRecordsKey"] = newMedicalHistoryKey; modified = true; } if (string.IsNullOrEmpty(jwtSecretKey)) { var newJwtSecretKey = KeyGenerator.GenerateJwtSecretKey(); json["Jwt"]["SecretKey"] = newJwtSecretKey; modified = true; } if (modified) File.WriteAllText(appSettingsPath, json.ToString()); } public static void EnsureMongoDatabaseAndCollectionsExist(IConfiguration configuration) { var mongoConnectionString = configuration["ConnectionStrings:MongoDBConnection"]; var mongoClient = new MongoClient(mongoConnectionString); var databaseName = configuration["HealthcareManagerDatabase:Name"]; var database = mongoClient.GetDatabase(databaseName); var requiredCollections = new List { configuration["HealthcareManagerDatabase:MedicalRecordCollectionName"], configuration["HealthcareManagerDatabase:ChatCollectionName"], configuration["HealthcareManagerDatabase:AppointmentsCollectionName"] }; var existingCollections = database.ListCollectionNames().ToList(); foreach (var collectionName in requiredCollections) if (!existingCollections.Contains(collectionName)) database.CreateCollection(collectionName); } public static void EnsureDatabaseCreated(HealthcareManagerDatabase dbContext) { if (dbContext.Database.GetPendingMigrations().Any()) dbContext.Database.Migrate(); } }