Refactor email services and update password handling

Updated `EmailAccountDto` to use `required` properties for .NET 7+ compatibility, removing the `PasswordEncrypted` property and simplifying password handling.

Removed `IEncryptionService` dependency from `LimilabsEmailService` and `LimilabsImapEmailService`. Updated `ConnectAndAuthenticateSmtpAsync` and `OpenAsync` methods to remove password decryption logic.

Introduced `CancellationToken` support in `LimilabsImapEmailService` methods to improve cancellation handling for IMAP operations.

Added `Entities\` folder reference in `DigitalData.MessagingService.Domain.csproj`.
This commit is contained in:
2026-08-12 14:24:17 +02:00
parent 176e6dd6c5
commit 5e0de6d52a
4 changed files with 24 additions and 29 deletions

View File

@@ -16,8 +16,7 @@ namespace DigitalData.MessagingService.Infrastructure.Services;
/// Uses the first account in the list whose <see cref="EmailAccountDto.Name"/> equals <c>"default"</c>,
/// or falls back to the first account if none is named "default".
/// </summary>
public class LimilabsEmailService(
IEncryptionService encryptionService) : IEmailService
public class LimilabsEmailService() : IEmailService
{
// Register encoding provider for Limilabs (requires windows-1252 and other code pages)
static LimilabsEmailService()
@@ -71,7 +70,7 @@ public class LimilabsEmailService(
}
}
private async Task ConnectAndAuthenticateSmtpAsync(Smtp smtp, EmailAccountDto smtpAccount)
private static async Task ConnectAndAuthenticateSmtpAsync(Smtp smtp, EmailAccountDto smtpAccount)
{
if (smtpAccount.SmtpUseSsl)
{
@@ -88,9 +87,7 @@ public class LimilabsEmailService(
}
else
{
var password = smtpAccount.PasswordEncrypted ? encryptionService.Decrypt(smtpAccount.Password) : smtpAccount.Password;
await smtp.LoginAsync(smtpAccount.Username, password);
await smtp.LoginAsync(smtpAccount.Username, smtpAccount.Password);
}
}

View File

@@ -31,9 +31,9 @@ public class LimilabsImapEmailService(
public async Task<IEnumerable<ReceivedEmailDto>> FetchEmailsAsync(
EmailAccountDto account,
MailSearchFilter filter,
CancellationToken cancellationToken = default)
CancellationToken cancel = default)
{
using var imap = await OpenAsync(account, filter.Folder);
using var imap = await OpenAsync(account, filter.Folder, cancel);
try
{
#region Find UIDs
@@ -51,7 +51,7 @@ public class LimilabsImapEmailService(
}
var searchExpression = criterions.Count > 0 ? Expression.And([.. criterions]) : Expression.All();
List<long> uids = [.. await imap.SearchAsync(searchExpression, cancellationToken)];
List<long> uids = [.. await imap.SearchAsync(searchExpression, cancel)];
if (filter.SortOrder == MailSortOrder.NewestFirst)
uids.Reverse();
@@ -64,7 +64,7 @@ public class LimilabsImapEmailService(
foreach (var uid in uids)
{
cancellationToken.ThrowIfCancellationRequested();
cancel.ThrowIfCancellationRequested();
try
{
@@ -73,9 +73,9 @@ public class LimilabsImapEmailService(
CacheKeyPrefix + uid,
async entry =>
{
var eml = await imap.GetMessageByUIDAsync(uid, cancellationToken);
var eml = await imap.GetMessageByUIDAsync(uid, cancel);
var mail = new MailBuilder().CreateFromEml(eml);
var flags = await imap.GetFlagsByUIDAsync(uid, cancellationToken);
var flags = await imap.GetFlagsByUIDAsync(uid, cancel);
var attachments = new List<EmailAttachmentDto>();
@@ -169,7 +169,7 @@ public class LimilabsImapEmailService(
}
}
await imap.CloseAsync(cancellationToken);
await imap.CloseAsync(cancel);
if (filter.MaxCount is int maxCount && maxCount > 0 && results.Count > maxCount)
return results.Take(maxCount);
@@ -194,13 +194,13 @@ public class LimilabsImapEmailService(
EmailAccountDto account,
long uid,
string folder = "INBOX",
CancellationToken cancellationToken = default)
CancellationToken cancel = default)
{
using var imap = await OpenAsync(account, folder);
using var imap = await OpenAsync(account, folder, cancel);
try
{
await imap.MarkMessageSeenByUIDAsync(uid, cancellationToken);
await imap.CloseAsync(cancellationToken);
await imap.MarkMessageSeenByUIDAsync(uid, cancel);
await imap.CloseAsync(cancel);
}
catch (Limilabs.Client.ServerException ex)
{
@@ -216,25 +216,21 @@ public class LimilabsImapEmailService(
}
}
private async Task<Imap> OpenAsync(EmailAccountDto account, string folder)
private static async Task<Imap> OpenAsync(EmailAccountDto account, string folder, CancellationToken cancel)
{
var imap = new Imap();
if (account.ImapUseSsl)
await imap.ConnectSSLAsync(account.ImapServer!, account.ImapPort);
await imap.ConnectSSLAsync(account.ImapServer!, account.ImapPort, cancel: cancel);
else
await imap.ConnectAsync(account.ImapServer!, account.ImapPort);
await imap.ConnectAsync(account.ImapServer!, account.ImapPort, cancel: cancel);
var password = account.PasswordEncrypted
? EncryptionService.Decrypt(account.Password)
: account.Password;
await imap.LoginAsync(account.Username, password);
await imap.LoginAsync(account.Username, account.Password, cancel);
if (string.Equals(folder, "INBOX", StringComparison.OrdinalIgnoreCase))
await imap.SelectInboxAsync();
await imap.SelectInboxAsync(cancel);
else
await imap.SelectAsync(folder);
await imap.SelectAsync(folder, cancel);
return imap;
}