NonInventPurchasingSystem/CPRNIMS.Domain/Services/SMTP/SMTP.cs
2026-01-20 07:44:30 +08:00

231 lines
8.3 KiB
C#

using CPRNIMS.Domain.Contracts.SMTP;
using CPRNIMS.Infrastructure.Database;
using CPRNIMS.Infrastructure.Dto.Items;
using CPRNIMS.Infrastructure.Dto.SMTP;
using CPRNIMS.Infrastructure.Entities.Purchasing;
using System.Security.Cryptography;
using CPRNIMS.Infrastructure.Entities.SMTP;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CPRNIMS.Domain.Services.SMTP
{
public class SMTP : ISMTP
{
private readonly NonInventoryDbContext _dbContext;
public SMTP(NonInventoryDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<List<SMTPCredential>> GetAllSmtp(SMTPCredentialDto itemDto)
{
try
{
var allItems = await _dbContext.SMTPCredentials
.FromSqlRaw($"EXEC GetAllSmtp @UserId = '{itemDto.UserId}'")
.ToListAsync();
return allItems ?? new List<SMTPCredential>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
}
private static readonly byte[] Key = GetPaddedKey("MDLD_1NV3NT0RY_2o24", 32);
public async Task<List<SMTPCredential>> GetSMTPCredential(SMTPCredentialDto itemDto)
{
try
{
var allCred = await _dbContext.SMTPCredentials
.FromSqlRaw($"EXEC GetSMTPCredential @UserId = '{itemDto.UserId}', @SMTPTypeId = {itemDto.SMTPTypeId}")
.ToListAsync();
foreach (var cred in allCred)
{
if (IsEncrypted(cred.Password))
{
cred.Password = DecryptString(cred.Password);
}
}
return allCred ?? new List<SMTPCredential>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
}
// Decrypt string method
private string DecryptString(string cipherText)
{
try
{
byte[] fullCipher = Convert.FromBase64String(cipherText);
byte[] iv = new byte[16];
byte[] cipherTextBytes = new byte[fullCipher.Length - 16];
Array.Copy(fullCipher, iv, iv.Length);
Array.Copy(fullCipher, iv.Length, cipherTextBytes, 0, cipherTextBytes.Length);
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
using (ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, iv))
using (MemoryStream msDecrypt = new MemoryStream(cipherTextBytes))
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
return srDecrypt.ReadToEnd();
}
}
}
catch (FormatException)
{
// If it's not a valid base64 string, it means it's already decrypted
return cipherText;
}
}
// Method to check if the password is encrypted
private bool IsEncrypted(string password)
{
try
{
// Try to convert from Base64
Convert.FromBase64String(password);
return true;
}
catch (FormatException)
{
// If it fails, it's not Base64 encoded, hence not encrypted
return false;
}
}
public async Task<List<SMTPCredential>> GetMySmtp(SMTPCredentialDto itemDto)
{
try
{
var allItems = await _dbContext.SMTPCredentials
/* .FromSqlRaw("EXEC GetMySmtp @UserId = {0}", itemDto.UserId, )*/
.FromSqlRaw($"EXEC GetMySmtp @UserId = '{itemDto.UserId}', @SMTPCredentialId = {itemDto.SMTPCredentialId}")
.ToListAsync();
//foreach (var item in allItems)
//{
// item.Password = DecryptString(item.Password);
//}
return allItems ?? new List<SMTPCredential>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
}
public async Task<SMTPCredential> GetMySmtpById(SMTPCredentialDto itemDto)
{
try
{
var sMTP = await _dbContext.SMTPCredentials
.FromSqlRaw($"EXEC GetMySmtp @UserId = '{itemDto.UserId}', @SMTPCredentialId = {itemDto.SMTPCredentialId}")
.ToListAsync();
if (sMTP.Count == 0)
{
return null; // No item found
}
var item = sMTP.First();
item.Password = DecryptString(item.Password);
return item;
}
catch (SqlException ex)
{
var message = ex.ToString();
throw;
}
}
public async Task<SMTPCredential> PostPutSmtp(SMTPCredentialDto itemDto)
{
try
{
// Encrypt the password
string encryptedPassword = EncryptString(itemDto.Password);
await _dbContext.Database
.ExecuteSqlRawAsync("EXEC PostPutSmtp " +
"@SMTPCredentialId, @SMTPCredentialName, @UserId, @SenderEmail, @SenderUserName," +
" @SenderDisplayName, @Password, @Server, @OutgoingPort, @IncomingPort ,@IsActive",
new SqlParameter("@SMTPCredentialId", itemDto.SMTPCredentialId != null ? itemDto.SMTPCredentialId : 0L),
//new SqlParameter("@SMTPTypeId", itemDto.SMTPTypeId),
new SqlParameter("@SMTPCredentialName", itemDto.SMTPCredentialName ?? "N/A"),
new SqlParameter("@UserId", itemDto.UserId),
new SqlParameter("@SenderEmail", itemDto.SenderEmail ?? "N/A"),
new SqlParameter("@SenderUserName", itemDto.SenderUserName ?? "N/A"),
new SqlParameter("@SenderDisplayName", itemDto.SenderDisplayName ?? "N/A"),
new SqlParameter("@Password", encryptedPassword),
new SqlParameter("@Server", itemDto.Server ?? "N/A"),
new SqlParameter("@OutgoingPort", itemDto.OutgoingPort),
new SqlParameter("@IncomingPort", itemDto.IncomingPort),
new SqlParameter("@IsActive", itemDto.IsActive));
return new SMTPCredential();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
}
private static byte[] GetPaddedKey(string key, int length)
{
var keyBytes = Encoding.UTF8.GetBytes(key);
if (keyBytes.Length >= length)
{
return keyBytes.Take(length).ToArray();
}
var paddedKey = new byte[length];
Buffer.BlockCopy(keyBytes, 0, paddedKey, 0, keyBytes.Length);
return paddedKey;
}
// Encrypt string
private string EncryptString(string plainText)
{
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.GenerateIV();
byte[] iv = aesAlg.IV;
using (ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, iv))
using (MemoryStream msEncrypt = new MemoryStream())
{
// Prepend the IV to the encrypted content
msEncrypt.Write(iv, 0, iv.Length);
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
return Convert.ToBase64String(msEncrypt.ToArray());
}
}
}
}
}