Commit Graph

180 Commits

Author SHA1 Message Date
6abe0e18f6 feat(application): add EmailSyncResult DTO, Folder/AccountId to ReceivedEmailDto, rename CreateRangeAsync in IRepository, update IImapEmailService signature, add AutoMapper profiles for ReceivedEmail and EmailAttachment 2026-08-13 16:48:22 +02:00
c9b7d99ecc feat(domain): add Folder property and change To/Cc to List<string> in ReceivedEmail 2026-08-13 16:48:06 +02:00
4964fa4344 Refactor IMAP service for repository integration
Replaced `FetchEmailsAsync` with `SyncEmailsAsync` in `IImapEmailService` to simplify email synchronization. Updated method signatures to use `DateFilter` and added default parameters for `folder` and `cancel`.

Refactored `LimilabsImapEmailService` to remove client-side filtering logic and delegate storage to `IRepository<ReceivedEmail>`. Simplified IMAP search criteria to focus on date-based filtering and added checks to skip already-synced emails.

Updated `EmailSyncWorker` to use the new `SyncEmailsAsync` method. Removed unused code, streamlined exception handling, and improved maintainability by reducing complexity and focusing on server-side filtering.
2026-08-13 14:18:43 +02:00
7207c5b4d9 Refactor email repository and query handling
Replaced `IMailRepository` with `IReceivedEmailRepository` to improve modularity and functionality. Updated `IReceivedEmailRepository` to make the `EmailAccount` parameter optional in the `FindAsync` method.

Added `ReceivedEmailRepository` with advanced filtering capabilities, including account, flags, text, UID, date, and recipient filters. Implemented deferred materialization for recipient filtering due to EF Core limitations.

Registered `IReceivedEmailRepository` in dependency injection. Updated `ReadEmailQueryHandler` to use the new repository. Improved query performance by applying filters conditionally.
2026-08-13 13:28:19 +02:00
7f04c4b09f Rename IMailRepository and add FindAsync method
Renamed the `IMailRepository` interface to `IReceivedEmailRepository`
to better reflect its purpose. Added a new `FindAsync` method to
the interface, which supports searching for received emails using
a `MailSearchFilter`, an `EmailAccount`, and an optional
`CancellationToken`. The method returns a `Task` resolving to
an `IEnumerable<ReceivedEmail>`.
2026-08-13 13:18:37 +02:00
43d7c393bb Refactor Repository to use protected DbSet field
Renamed `_dbSet` to `DbSet` and changed its accessibility from
`private` to `protected` to allow access in derived classes.

Updated all methods in the `Repository` class to use the new
`DbSet` field for querying, adding, updating, and removing
entities. This includes methods like `CreateAsync`,
`GetByIdAsync`, `FindAsync`, `UpsertAsync`, `UpdateAsync`,
and `DeleteAsync`.

Improved code consistency and readability by removing
redundant `_dbSet` references and standardizing on the
`DbSet` field.
2026-08-13 13:17:43 +02:00
e73bead2f2 Refactor email fetching to use IMailRepository
Introduced a new `IMailRepository` interface to abstract email-fetching logic, replacing the direct dependency on `IImapEmailService` in `ReadEmailQueryHandler`. Updated `ReadEmailQueryHandler` to use `IMailRepository` for querying emails and added `IMapper` for mapping entities to DTOs.

Modified the constructor of `ReadEmailQueryHandler` to inject `IMailRepository`, `IMapper`, and renamed `IRepository<EmailAccount>` to `EmailAccountRepo`. Replaced `IImapEmailService.FetchEmailsAsync` with `IMailRepository.FindAsync` in the handler's `Handle` method.

Wrapped all changes in `#if NET` preprocessor directives to ensure compatibility with specific build configurations. These changes improve modularity, testability, and separation of concerns.
2026-08-13 13:11:18 +02:00
606ff94a77 Rename FetchEmailsQuery to ReadEmailQuery
Renamed `FetchEmailsQuery` to `ReadEmailQuery` across the codebase, including its handler, validator, and usages in `EmailController`. Updated method signatures, dependencies, and XML documentation to reflect the new naming convention. Adjusted `ILogger` dependency in the handler to match the renamed class.
2026-08-13 12:09:44 +02:00
1c9af0e560 Remove caching from LimilabsImapEmailService
Simplified the `LimilabsImapEmailService` by removing the dependency on `IMemoryCache` and eliminating all caching logic. The constructor no longer accepts an `IMemoryCache` parameter, and the static `CacheKeyPrefix` field has been removed.

Replaced the caching mechanism with direct email fetching using `imap.GetMessageByUIDAsync`. Refactored the logic for processing attachments and visuals into `EmailAttachmentDto` objects, and streamlined the construction of `ReceivedEmailDto` to include metadata directly from the fetched email data.

These changes reduce complexity, improve maintainability, and ensure the service always retrieves the latest email data from the IMAP server.
2026-08-13 12:07:20 +02:00
86a07e5017 feat(api): handle BadRequestException as HTTP 400 and add EmailAccountController
- ExceptionHandlingMiddleware: map BadRequestException to 400 Bad Request response
- Add EmailAccountController: GET /email-accounts (with optional Id/Username filter),
  POST/PUT/DELETE via EmailAccountModificationCommand for full CRUD over email accounts
2026-08-13 11:58:25 +02:00
25d0c009ee refactor(infrastructure): migrate EmailSyncWorker to DB-backed account source with upsert seed
- EmailSyncWorker now fetches active email accounts from IRepository<EmailAccount>
  on every polling cycle instead of reading from static options list
- Add UpsertSeedEmailAccount: on startup, seed accounts from EmailAccountsOptions
  into the database via IRepository.UpsertAsync (insert or update by Username)
- Remove standalone EmailAccountSyncWorker (merged into EmailSyncWorker)
2026-08-13 11:58:12 +02:00
14180860d3 refactor(application): replace ISender dispatch with direct IRepository usage in email handlers
- FetchEmailsQuery, MarkEmailAsSeenCommand, PublishEmailCommand: resolve EmailAccount
  via IRepository<EmailAccount> instead of dispatching GetEmailAccountQuery through ISender
- Swap InvalidOperationException for BadRequestException when IMAP server is not configured
- Add ILogger to handlers; warn when multiple accounts match the lookup criteria
- EmailAccountsOptions.Accounts now typed as IEnumerable<EmailAccountModificationDto>
  instead of IEnumerable<EmailAccount> to decouple config from domain entity
- EmailMappingProfile: add EmailAccount <-> EmailAccountDto/EmailAccountModificationDto maps
2026-08-13 11:57:57 +02:00
50eaefb868 refactor(application): replace GetSenderQuery with GetEmailAccountQuery and add EmailAccountModificationCommand
- Rename GetSenderQuery to GetEmailAccountQuery with updated return type (IEnumerable<EmailAccountDto>)
- Handler now queries IRepository<EmailAccount> directly instead of chaining MediatR dispatches
- Add EmailAccountModificationCommand for create/update/delete operations on email accounts
- Update GetSenderQueryValidator to reference renamed query type
- Remove exclusive Id/Username validation rule (now handled by repo query logic)
2026-08-13 11:57:39 +02:00
84da5cb646 feat(application): add EmailAccount DTOs and Modification value object 2026-08-13 11:57:25 +02:00
25b55ef651 feat(domain): add BadRequestException for invalid request errors 2026-08-13 11:57:12 +02:00
8b4d1e48f5 Add EmailAccountSyncWorker and configure EmailAccount entity
Introduced the `EmailAccountSyncWorker` background service to initialize and synchronize email accounts using RabbitMQ for event-driven processing. The service resolves email account configurations from application settings and upserts them into the repository.

Updated `MessagingServiceDbContext` to configure the `EmailAccount` entity, setting the `Username` property to use the `SQL_Latin1_General_CP1_CI_AS` collation for case-insensitive comparisons.

Added necessary `using` directives in `DependencyInjection.cs` to integrate new dependencies for AutoMapper, repositories, services, and background processing.
2026-08-13 09:37:39 +02:00
893addb45d Add AutoMapper profile for entity self-mappings
Introduce `EntitySelfMappingProfile` to enable self-mappings (T -> T) for domain entities (`EmailAccount`, `ReceivedEmail`, `EmailAttachment`). This ensures uniform AutoMapper usage in the generic repository, regardless of whether the target type is a DTO or the entity itself. Added necessary `using` directives for `AutoMapper` and domain entities.
2026-08-13 09:37:14 +02:00
00ae8e1ba0 Add bulk create and upsert methods to repository
Added `CreateAsync` for bulk entity creation and `UpsertAsync`
and `UpsertSingleAsync` for upsert operations in `IRepository`
and `Repository`. Improved error handling in `UpdateSingleAsync`
and `DeleteSingleAsync` by throwing `NotFoundException` when no
matching entity is found. Refactored `FindAsync` and `UpdateAsync`
for better readability and performance. Cleaned up formatting in
`DeleteAsync`.
2026-08-13 09:36:48 +02:00
5c37b2ef92 Add EF Core In-Memory DB and repository pattern support
Added the `Microsoft.EntityFrameworkCore.InMemory` package to enable an in-memory database for testing and lightweight storage. Introduced `MessagingServiceDbContext` with `DbSet` properties for `EmailAccount`, `ReceivedEmail`, and `EmailAttachment`. Configured entity relationships in `OnModelCreating`.

Registered `MessagingServiceDbContext` and a generic repository (`IRepository<>`) in the dependency injection container. Updated namespaces and imports to support the new DbContext and repository.

Improved project structure to enhance modularity and testability by leveraging EF Core's in-memory database.
2026-08-12 16:18:35 +02:00
be28a61d9c Add email domain entities and .NET Framework support
Introduced `EmailAccount`, `EmailAttachment`, and `ReceivedEmail`
entities with database mappings using data annotations. These
entities represent email account configurations, attachments,
and received emails, respectively.

Added conditional compilation to ensure compatibility between
.NET and .NET Framework. Updated `DigitalData.MessagingService.Domain.csproj`
to include `System.ComponentModel.DataAnnotations` for `net462`.

Defined relationships between entities, including navigation
properties and foreign key constraints.
2026-08-12 16:08:29 +02:00
b2857c558f Refactor: Replace EmailAccountDto with EmailAccount
Replaced the `EmailAccountDto` class with the `EmailAccount` class across the codebase to consolidate the `EmailAccount` entity into the domain layer. Updated namespaces, method signatures, property types, and test cases to reflect this change.

Moved `EmailAccount` from `DigitalData.MessagingService.Application.Common.Dto` to `DigitalData.MessagingService.Domain.Entities`. Updated XML documentation and removed redundant project file entries. Adjusted namespaces for related queries, validators, and commands to align with the new structure.

These changes improve separation of concerns and align with domain-driven design principles.
2026-08-12 15:26:15 +02:00
91581649ba Refactor namespaces and remove Abstraction project
Replaced `DigitalData.MessagingService.Abstraction` with
`DigitalData.MessagingService.Application.Common.Dto` and
`DigitalData.MessagingService.Application.Common.Dto.MailSearch`
to improve modularity and organization.

Removed the `Abstraction` project and updated all references
to use the `Application` project. Updated namespaces, `using`
directives, and dependencies across the codebase.

Refactored interfaces, commands, queries, validators, and
services to use the new DTOs. Updated RabbitMQ integration,
AutoMapper profiles, background services, and tests to align
with the new structure.

Performed general cleanup by removing redundant `using`
directives and obsolete references.
2026-08-12 15:13:15 +02:00
4dd0974c6f Add multi-targeting support for .NET frameworks
Introduced conditional compilation using `#if NET` directives to
enable support for multiple frameworks (`net462`, `net480`, and
`net8.0`). Updated the project file to support multi-targeting
and added framework-specific dependencies conditionally.

Refactored namespaces, interfaces, classes, validators, and
handlers to ensure compatibility with targeted frameworks.
Enhanced dependency injection setup and adjusted logic in
`GetSenderQueryHandler` for framework-specific behavior.

Ensured consistency and maintainability by wrapping framework-
specific code blocks with `#if NET` directives.
2026-08-12 14:40:47 +02:00
5e0de6d52a 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`.
2026-08-12 14:24:17 +02:00
176e6dd6c5 Refactor: Replace EmailAttachmentContext with DTO
Replaced `EmailAttachmentContext` with `EmailAttachmentDto` across the codebase to align with the updated DTO naming convention.

- Renamed `EmailAttachmentContext` to `EmailAttachmentDto`.
- Updated property types, method signatures, and return types to use `EmailAttachmentDto`.
- Modified XML documentation references to reflect the new class name.
- Updated `ReceivedEmailContext` to `ReceivedEmailDto` and adjusted related methods and properties.
- Refactored `FetchEmailsAsync` methods and handlers to use `ReceivedEmailDto`.
- Adjusted `BuildAttachmentsAsync` and attachment handling logic in `EmailController` and `LimilabsImapEmailService`.

This refactor ensures consistency and improves code clarity while maintaining functionality.
2026-08-12 14:17:24 +02:00
48796d9917 Refactor email filtering logic in LimilabsImapEmailService
Simplify email filtering by removing server-side filtering logic
and replacing it with in-process filtering after email retrieval.
Eliminate the use of `ICriterion` and `Expression` constructs,
and move all filtering conditions (e.g., `UnseenOnly`,
`SubjectContains`, `SenderContains`, etc.) into the processing
loop.

Add an `IsSeen` property to `ReceivedEmailContext` to track
email read status. Apply `filter.MaxCount` after all filtering
and processing are complete. Update `filter.WithAttachments`
logic to conditionally include attachments in results.

Improve code readability and maintainability by consolidating
filtering logic into a single location, ensuring consistent
application of all filters.
2026-08-12 13:41:35 +02:00
f6ada2ad9e Refactor LimilabsImapEmailService for clarity and efficiency
Refactored the `LimilabsImapEmailService` class to improve email fetching and processing. Consolidated logic by inlining and removing redundant private helper methods (`FetchEmailUidsAsync` and `FetchEmailByUidAsync`). Introduced structured `#region` blocks for UID fetching and email reading.

Enhanced filtering capabilities with support for unseen emails, subject, sender, recipient, body, UID ranges, and date ranges. Improved attachment handling by categorizing inline and regular attachments into `EmailAttachmentContext`. Added conditional attachment inclusion based on `filter.WithAttachments`.

Integrated caching (`Cache.GetOrCreateAsync`) to avoid redundant email fetches. Improved error handling and logging for better fault tolerance. Overall, the changes simplify the codebase, improve readability, and enhance functionality.
2026-08-12 13:01:49 +02:00
7b5596f3e5 Refactor email fetching methods in Limilabs service
Removed public methods `FetchEmailUidsAsync` and `FetchEmailByUidAsync` from `LimilabsImapEmailService` to simplify the public API.

Refactored `FetchEmailUidsAsync` into a private static helper method that operates directly on an `Imap` instance.

Removed exception handling logic specific to the removed methods. These changes aim to encapsulate email fetching functionality and streamline the service's design.
2026-08-12 12:45:52 +02:00
5d3997b7e1 Remove MarkAsSeen endpoint from EmailController
The `MarkAsSeen` method in the `EmailController` class has been removed. This method provided an HTTP PATCH endpoint at the route `"seen"` to mark a single IMAP message as seen (read). It accepted a `MarkEmailAsSeenCommand` and a `CancellationToken`, used `mediator.Send` to process the command, and returned an HTTP 204 No Content response upon success.

The removal of this method eliminates the ability to mark emails as seen via this endpoint.
2026-08-12 12:43:31 +02:00
cb3b2e09ab Refactor email fetching logic in EmailController
Consolidated email fetching endpoints by removing `FetchEmailUids`
and `FetchEmailByUid` endpoints and integrating their functionality
into the `FetchEmails` method. Introduced an `OnlyFilter` enum to
allow filtering responses for HTML body or UIDs. Removed related
methods (`FetchEmailUidsAsync`, `FetchEmailByUidAsync`) from
`IImapEmailService` and deleted associated query classes and
handlers.
2026-08-12 12:42:15 +02:00
118612206e Refactor IMAP initialization with OpenAsync helper
Refactored IMAP object initialization and folder selection into a new `OpenAsync` helper method to reduce code duplication and improve maintainability.

- Replaced repetitive connection, authentication, and folder selection logic in multiple methods (`FetchEmailsAsync`, `FetchEmailUidsAsync`, etc.) with `OpenAsync`.
- Removed `ConnectAndAuthenticateAsync` and `SelectFolderAsync` methods, as their functionality is now encapsulated in `OpenAsync`.
- Updated `FetchEmailUidsAsync` to remove the `EmailAccountDto account` parameter, delegating connection logic to `OpenAsync`.
- Ensured all methods now use `OpenAsync` to obtain a fully prepared `Imap` instance, improving clarity and reducing error risk.
2026-08-12 12:33:52 +02:00
a446162afa Add EmailSyncWorker and enhance IMAP service with caching
Refactored `ReceivedEmailContext` to use `record` for immutability
and value-based equality. Added `SyncIntervalSeconds` to
`EmailAccountsOptions` for configuring IMAP sync intervals.

Introduced `EmailSyncWorker` as a background service for periodic
email synchronization. Registered `IMemoryCache` and integrated
caching in `LimilabsImapEmailService` to reduce redundant fetch
operations. Optimized `FetchEmailByUidAsync` to conditionally
handle attachments and improve performance.

Refactored logging and improved code readability by adopting modern
C# features like `record`, `with` expressions, and `IOptions`.
Performed general cleanup and streamlined method implementations.
2026-08-12 11:48:29 +02:00
f521683608 /s
Simplify IMAP email fetching API and refactor logic

Removed `markAsSeen` parameter from `FetchEmailsAsync` and
`FetchEmailByUidAsync` methods in `IImapEmailService` to
simplify the API. Updated `MailSearchFilter` to make `MaxCount`
nullable for greater flexibility.

Removed `markAsSeen` from `FetchEmailByUidQuery` and
`FetchEmailsQuery` records and their handlers. Deleted
`FetchEmailByUidQueryValidator` as it is no longer needed.

Refactored `LimilabsImapEmailService`:
- Introduced `FetchEmailUidsAsync` to centralize UID fetching logic.
- Simplified `FetchEmailByUidAsync` using a new helper method.
- Consolidated connection, authentication, and folder selection
  into reusable private methods.
- Removed redundant code for search criteria and flag fetching.

Removed `IsSeen` from `ReceivedEmailContext` and improved
overall code readability and maintainability by reducing
duplication and centralizing logic.
2026-08-12 10:04:48 +02:00
f3761e96d9 refactor(imap): remove connection pool, revert to per-call Imap, add batch flags fetch
- ImapConnectionPool removed (over-engineered; IMAP server allows multiple concurrent connections)
- LimilabsImapEmailService reverted to stateless per-call new Imap() pattern (same as original)
- GetFlagsByUIDAsync(List<long>) replaces per-message GetFlagsByUID — one round-trip for all flags
- markAsSeen wired through: GetMessageByUIDAsync (true) vs PeekMessageByUIDAsync (false)
- DependencyInjection: pool registration removed, service registered directly as before
2026-08-11 15:52:17 +02:00
e840d026aa feat(imap): add markAsSeen option to fetch queries and interface
- IImapEmailService.FetchEmailsAsync / FetchEmailByUidAsync now accept
  a bool markAsSeen = true parameter
- FetchEmailsQuery and FetchEmailByUidQuery expose MarkAsSeen { init; } = true
- markAsSeen=true  uses BODY[]      (server sets \\Seen, legacy-compatible)
- markAsSeen=false uses BODY.PEEK[] (non-destructive read, flag untouched)
2026-08-11 15:51:57 +02:00
962cb52e0b Enhance EmailController with new endpoint and improvements
- Changed HTML body response handling to return Content with
  "text/html" content type for better response clarity.
- Added a new `FetchEmailUids` endpoint to retrieve only email
  UIDs based on query filters, with proper status handling.
- Updated `FetchEmailByUid` to support an optional `htmlBodyOnly`
  parameter, allowing clients to fetch only the HTML body.
- Added XML documentation for new and updated methods.
- Improved response handling and ensured proper HTTP status codes.
2026-08-11 10:03:22 +02:00
1162a07454 Add FetchEmailByUid endpoint and improve middleware
Added a new endpoint to `EmailController` for fetching a single email by UID, including route and query parameter handling, and appropriate Swagger annotations.

Refactored `ExceptionHandlingMiddleware` to use constructor injection, simplified exception handling with a `switch` expression, and improved logging and response formatting. Added support for `ValidationException`.

Updated `FormatValidationErrors` to handle `ValidationException` and improved error formatting.

Made minor documentation updates in `EmailController` and performed general code cleanup for readability and modernization.
2026-08-11 09:48:22 +02:00
59e8780345 Add FetchEmailUidsQuery and its handler for IMAP UIDs
Introduced `FetchEmailUidsQuery` to retrieve UIDs of matching
emails from an IMAP mailbox. Added the `FetchEmailUidsQuery`
record with properties for email account (`GetSenderQuery`)
and mail filtering (`MailSearchFilter`).

Implemented `FetchEmailUidsQueryHandler` to handle the query.
The handler validates the email account, ensures IMAP
configuration, and uses `IImapEmailService.FetchEmailUidsAsync`
to fetch UIDs. Added necessary `using` directives for
dependencies.
2026-08-11 09:46:26 +02:00
5ff38391d0 Add FetchEmailByUidQuery with handler and validation
Introduced `FetchEmailByUidQuery` to fetch a single email by its
UID from an IMAP mailbox. The query includes properties for
email account, UID, folder, and attachment inclusion, with a
fluent method `WithUid(long uid)` to set the UID.

Added `FetchEmailByUidQueryHandler` to process the query,
leveraging `ISender` for account retrieval and `IImapEmailService`
for email fetching. Included error handling for missing accounts
and misconfigured IMAP settings.

Implemented `FetchEmailByUidQueryValidator` to validate the
query, ensuring the `Account` is not null, `Uid` is set and
greater than 0, and `Folder` is not empty.
2026-08-11 09:45:21 +02:00
1fb7dcf98a Add methods for fetching email UIDs and emails by UID
Added `FetchEmailUidsAsync` to `IImapEmailService` for retrieving UIDs of emails matching a filter, optimizing scenarios where only identifiers are needed. Added `FetchEmailByUidAsync` to fetch a single email by UID, with optional attachment handling.

Implemented `FetchEmailUidsAsync` in `LimilabsImapEmailService` to connect to the IMAP server, construct search criteria, retrieve UIDs, and handle sorting and result limits. Added robust error handling for authentication and other failures.

Implemented `FetchEmailByUidAsync` in `LimilabsImapEmailService` to fetch email content and flags for a specific UID, map the data to `ReceivedEmailContext`, and handle errors with logging for non-critical failures.
2026-08-11 09:42:04 +02:00
ee279c407b Remove HasAttachments filter; enhance FetchEmails response
The `MailSearchFilter` class was updated to remove the `HasAttachments` property, simplifying the filtering logic. Corresponding client-side filtering logic in `LimilabsImapEmailService` was also removed. The IMAP search query now defaults to `Expression.All` when no criteria are provided.

The `FetchEmails` method in `EmailController` was enhanced with a new optional `firstHtmlBodyOnly` parameter. This allows returning only the HTML body of the first email or a `404 Not Found` response if no emails match the criteria. These changes improve flexibility and simplify the codebase.
2026-08-10 14:22:45 +02:00
74ec00ddd3 Refactor attachment handling in email fetching
Consolidate `WithAttachments` behavior into `MailSearchFilter` to simplify the API and reduce redundancy.

- Removed `withAttachments` parameter from `FetchEmailsAsync` in `IImapEmailService`.
- Added `WithAttachments` property to `MailSearchFilter` to control attachment inclusion.
- Removed `WithAttachments` property from `FetchEmailsQuery` as it is now encapsulated in `MailSearchFilter`.
- Updated `FetchEmailsQueryHandler` to use `MailSearchFilter` for attachment handling.
- Refactored `LimilabsImapEmailService` to use `MailSearchFilter.WithAttachments` for mapping email data.

These changes improve maintainability and clarity by centralizing attachment-related options in `MailSearchFilter`.
2026-08-10 12:05:27 +02:00
763ba67d34 Add support for optional email attachments fetching
Introduced a `withAttachments` parameter to the `FetchEmailsAsync` method in `IImapEmailService` and related layers, allowing callers to include or exclude attachment data when fetching emails. Updated `FetchEmailsQuery` and `FetchEmailsQueryHandler` to propagate this parameter.

Refactored `LimilabsImapEmailService` to conditionally process attachments and inline visuals based on the `withAttachments` flag, improving performance when attachments are not required. Replaced `Flag.Unseen` with `Expression.HasFlag(Flag.Unseen)` for better criteria handling. Cleaned up attachment-processing logic for improved readability and maintainability.
2026-08-10 11:54:35 +02:00
8e2e9af451 Refactor email search with new filter models
Replaced the old `SearchFilter` with the new `MailSearchFilter` model to enable more flexible and granular email search criteria. Introduced `DateFilter`, `UidFilter`, and `MailSortOrder` to support advanced filtering options such as date ranges, UID ranges, and sorting order. Updated `IImapEmailService` and `FetchEmailsQuery` to use the new models.

Added validators (`DateFilterValidator`, `MailSearchFilterValidator`, `UidFilterValidator`) to ensure input correctness. Refactored `LimilabsImapEmailService` to dynamically construct IMAP search queries based on the new filter properties, supporting unseen messages, text filters, and client-side attachment filtering.

Improved maintainability and scalability by cleaning up redundant code and leveraging the new models and validation framework.
2026-08-07 14:52:28 +02:00
53ba40b316 Refactor IMAP email fetching to use SearchFilter
Replaced individual parameters (`folder`, `unseenOnly`, `maxCount`) in `IImapEmailService` with a consolidated `SearchFilter` object to simplify method signatures and improve maintainability.

Renamed `MailQuery` to `SearchFilter` in `FetchEmailsQuery` for better clarity. Updated `FetchEmailsQueryHandler` and `LimilabsImapEmailService` to use the new `SearchFilter` object, ensuring consistent handling of folder selection, unread message filtering, and message count limits.

Improved logging in `LimilabsImapEmailService` to reflect the updated `SearchFilter` structure.
2026-08-07 13:25:13 +02:00
52a416f6d9 Refactor FetchEmailsQuery and improve UID handling
Moved the `Folder` property from `FetchEmailsQuery` to the
`MailQuery` record to better encapsulate query parameters.
Updated `FetchEmailsQueryHandler` to use `MailQuery.Folder`
for improved modularity. Simplified UID limiting logic in
`LimilabsImapEmailService` by replacing `Take().ToList()`
with the more concise `[.. Take()]` syntax.
2026-08-07 12:51:32 +02:00
79db1c3a69 Refactor email query and controller endpoints
Refactored `FetchEmailsQuery` to encapsulate filtering and retrieval parameters (`UnseenOnly` and `MaxCount`) within a nested `MailQuery` record for better organization. Updated `FetchEmailsQueryHandler` to use the new structure.

Simplified `EmailController` endpoints:
- Replaced multiple query parameters in `FetchEmails` with a single `FetchEmailsQuery` object.
- Replaced multiple parameters in `MarkAsSeen` with a `MarkEmailAsSeenCommand` object.
- Adjusted the HTTP route for `MarkAsSeen` from `"{uid}/seen"` to `"seen"`.

Updated XML documentation to reflect these changes, improving maintainability and scalability.
2026-08-07 12:43:41 +02:00
18c5dca9f4 Rename EmailsController to EmailController
Updated the class name from EmailsController to EmailController to follow a singular naming convention for controller classes. The namespace and constructor signature remain unchanged. This change improves consistency and readability in the codebase without introducing any functional modifications.
2026-08-07 11:50:48 +02:00
c47d78112c Add IMAP support for email fetching and marking as seen
Introduced IMAP functionality to enable fetching emails from an
IMAP server and marking messages as seen. Updated the
`EmailAccountDto` class with IMAP-related properties
(`ImapServer`, `ImapPort`, `ImapUseSsl`) for configuration.

Added `ReceivedEmailContext` to represent received emails and
created the `IImapEmailService` interface with methods
`FetchEmailsAsync` and `MarkAsSeenAsync`. Implemented the
`LimilabsImapEmailService` class using Limilabs Mail.dll for
IMAP operations, including connection handling, email fetching,
and marking messages as seen.

Added `FetchEmailsQuery` and `MarkEmailAsSeenCommand` with
handlers to encapsulate IMAP logic. Updated `EmailsController`
with new endpoints for fetching emails and marking messages as
seen. Registered `IImapEmailService` in `DependencyInjection`.

Included exception handling and logging for robust error
management during IMAP operations.
2026-08-07 11:48:12 +02:00
20de7da93d Rename SendEmailCommand to PublishEmailCommand
Refactor the codebase to rename `SendEmailCommand` and its associated components to `PublishEmailCommand` for improved clarity and consistency.

- Updated mapping in `EmailMappingProfile.cs` to use `PublishEmailCommand` instead of `SendEmailCommand`.
- Renamed `SendEmailCommand` to `PublishEmailCommand` in `PublishEmailCommand.cs`, including its methods like `WithAttachments`.
- Renamed `SendEmailCommandHandler` to `PublishEmailCommandHandler` and updated its method signature to handle the new command.
- Renamed `SendEmailCommandValidator` to `PublishEmailCommandValidator` and updated validation rules accordingly.
- Updated the `SendEmail` action in `EmailsController.cs` to accept `PublishEmailCommand` instead of `SendEmailCommand`.

These changes ensure consistency across the codebase and better reflect the purpose of the command.
2026-08-06 12:07:39 +02:00