Commit Graph

222 Commits

Author SHA1 Message Date
5ba650356a chore(api): bump version to 2.1.0-beta
Version bump for the health check endpoint and dashboard release.
2026-11-02 10:11:19 +01:00
292b6e9f36 feat(api): expose /health endpoint and health dashboard
Wire the infrastructure health checks into ASP.NET Core:

- /health returns JSON via UIResponseWriter and maps Unhealthy to HTTP 503
- /health-ui renders a Razor Pages dashboard with per-check status, description, tags and duration
- Tag health checks (rabbitmq, workers, ready, live) for monitoring filters
- Link the dashboard from the Swagger description and the page layout
2026-11-02 10:11:14 +01:00
2fdc8982aa feat(infrastructure): publish worker status to health checks
ConsumerInitWorker marks ConsumerInitHealthCheck as unhealthy when the consumer pool fails to start, so callers receive HTTP 503 instead of a silently degraded service.

EmailSyncWorker now reports its startup interval and the result of every sync cycle. SyncAccountAsync returns whether the account failed, letting the worker count errors per cycle and expose them through EmailSyncWorkerHealthCheck.
2026-11-02 10:10:55 +01:00
be881ea7c9 feat(infrastructure): add health checks for RabbitMQ and email sync worker
Introduce singleton health checks that background workers update at runtime:

- ConsumerInitHealthCheck reports whether the RabbitMQ consumer pool started
- RabbitMqConnectionHealthCheck opens a channel to verify broker reachability
- EmailSyncWorkerHealthCheck detects stalled or erroring sync cycles

Register all three in the infrastructure DI container so the API layer can wire them into the health check pipeline.
2026-11-02 10:10:51 +01:00
76fc005b02 Replace AsyncInitWorker with ConsumerInitWorker
Replaced the `AsyncInitWorker` background service with the new `ConsumerInitWorker`, which introduces enhanced error handling, logging, and configurability for RabbitMQ consumer initialization.

Updated `MessagingServiceDbContext` to remove the `UseCollation` configuration for the `Username` property in the `EmailAccount` entity, ensuring compatibility with the InMemory database.

Added the `ContinueOnInitFailure` property to `RabbitMqConfiguration` to allow the application to continue running if RabbitMQ consumer initialization fails.

Cleaned up unused `using` directives in `DependencyInjection.cs` and removed the obsolete `AsyncInitWorker` class.
2026-08-18 16:38:25 +02:00
26c78d32ae Remove encryption service and related configurations
The `IEncryptionService` interface and its implementation,
`DataProtectionEncryptionService`, have been removed from the
codebase. These components previously provided encryption and
decryption functionality using the ASP.NET Core Data Protection API.

Additionally, the dependency injection setup for the encryption
service and the Data Protection API configuration (e.g., key
persistence and application name) have been removed from
`DependencyInjection.cs`.
2026-08-18 15:49:44 +02:00
57ba948fe6 Update base path for configuration loading
Replaced `Directory.GetCurrentDirectory()` with `AppContext.BaseDirectory` in `Program.cs` to set the base path for configuration loading. This ensures configuration files are loaded relative to the application's runtime location instead of the current working directory.
2026-08-18 15:49:30 +02:00
8450806916 Refactor email fetching and handling logic
Consolidated email fetching queries into a unified `ReadEmailQuery` to support multiple protocols (IMAP, IMAP OAuth2, POP3) dynamically. Removed redundant query handlers (`ReadEmailViaImapQuery`, `ReadEmailViaOAuth2Query`, `ReadEmailViaPop3Query`) and merged their functionality into `ReadEmailQueryHandler` with protocol-specific methods.

Updated `FetchEmailsQueryValidator` to validate the new query. Refactored `EmailController` to use the unified query, simplifying endpoints and consolidating functionality. Removed obsolete endpoints for POP3 and OAuth2 fetching.

Performed code cleanup, including removing redundant imports and consolidating attachment handling logic. Updated project version to `2.0.0-beta` to reflect these significant changes. Improved documentation to align with the new structure.
2026-08-18 15:26:21 +02:00
acf40684f8 refactor: rename ReadEmailQuery to ReadEmailViaImapQuery, rename PublishEmailCommand to PublishEmailViaSmtpCommand 2026-08-17 17:03:59 +02:00
993d9cfea0 refactor(api): inject IEmailSyncService into SyncController; change OAuth2 authorize route to username param; add Swagger UI metadata and description links 2026-08-17 16:05:43 +02:00
8925428e46 feat(infrastructure): implement IEmailSyncService on EmailSyncWorker with rate-limited ForceTriggerSync via IMemoryCache; register as singleton in DI 2026-08-17 16:05:30 +02:00
c189a2d6ef refactor(application): change GetOAuth2AuthorizationUrlQuery to look up account by Username instead of Id 2026-08-17 16:05:16 +02:00
408ad14c9f feat(application): add IEmailSyncService interface and ForcedSyncIntervalSeconds option to EmailAccountsOptions 2026-08-17 16:05:02 +02:00
08547a8768 docs: add full OAuth2 setup guide for Google and Microsoft to README; exclude Google OAuth2 token JSON from version control 2026-08-17 15:06:51 +02:00
5746d36665 feat(api): add OAuth2Controller (Google authorize/callback), SyncController (on-demand trigger); register IHttpContextAccessor 2026-08-17 15:06:38 +02:00
a9046e957b feat(infrastructure): add TriggerSync to EmailSyncWorker for on-demand immediate sync; fix cancellation propagation after delay 2026-08-17 15:06:24 +02:00
3ddd5e83a2 feat(infrastructure): register Google OAuth2 services and dispatcher; add Microsoft.Extensions.Http package reference 2026-08-17 15:06:11 +02:00
6ff01b364c refactor(infrastructure): add provider guard and tenant ID validation to MicrosoftOAuth2TokenService; improve XML docs 2026-08-17 15:05:57 +02:00
bb9ff9c9ed feat(infrastructure): add GoogleOAuth2TokenService, GoogleOAuth2AuthorizationService and OAuth2TokenServiceDispatcher 2026-08-17 15:05:43 +02:00
ba8f701223 feat(application): add OAuth2RefreshToken/OAuth2Provider to DTOs; guard refresh token from being overwritten on seed; add OAuth2MappingProfile 2026-08-17 15:05:28 +02:00
6d6e876d94 feat(application): add OAuth2 authorization flow commands and queries (GetGoogleAuthorizationUrl, CompleteGoogleAuthorization) 2026-08-17 15:05:12 +02:00
502ae5e07b feat(application): add IOAuth2AuthorizationService interface and UpdateAccountOAuth2RefreshTokenCommand handler 2026-08-17 15:04:57 +02:00
c90040db67 feat(domain): add OAuth2Provider enum and OAuth2RefreshToken/OAuth2Provider fields to EmailAccount 2026-08-17 15:04:41 +02:00
f0c698856d refactor(infrastructure): dispatch EmailSyncWorker by IncomingProtocol, add POP3 sync path, use await using for scopes 2026-08-17 10:48:56 +02:00
158b562007 feat(domain/application): add IncomingProtocol field to EmailAccount entity and account DTOs 2026-08-17 10:48:45 +02:00
a0f1fcddac feat(domain): add IncomingProtocol enum (None, Imap, Pop3, ImapOAuth2, Pop3OAuth2) 2026-08-17 10:48:33 +02:00
f7d5abb132 feat(api): add IMAP send, POP3 receive, OAuth2 send/receive endpoints to EmailController 2026-08-17 10:16:04 +02:00
7782e86db3 feat(infrastructure): inject IServiceScopeFactory into consumer pool for scoped IMAP access and register new services (OAuth2, POP3) 2026-08-17 10:15:52 +02:00
1d7f269fe1 feat(infrastructure): add OAuth2 auth support and SendAndAppend capability to LimilabsEmailService and LimilabsImapEmailService 2026-08-17 10:15:38 +02:00
a13380016d feat(infrastructure): implement MicrosoftOAuth2TokenService and LimilabsPop3EmailService 2026-08-17 10:15:26 +02:00
822c7b1352 feat(application): register AutoMapper mappings for new commands and add SendAndAppend to IImapEmailService 2026-08-17 10:15:13 +02:00
f7e95eb7f7 feat(application): add PublishEmailViaImap/OAuth2 commands and ReadEmailViaPop3/OAuth2 queries with handlers 2026-08-17 10:14:59 +02:00
a57429718d feat(application): extend DTOs with POP3/OAuth2 fields and add IMAP append flags to SendingEmailEvent 2026-08-17 10:14:44 +02:00
ef8df96e65 feat(application): add IOAuth2TokenService and IPop3EmailService interfaces 2026-08-17 10:14:31 +02:00
194ae11a40 feat(domain): add POP3 and OAuth2 credential fields to EmailAccount entity 2026-08-17 10:14:18 +02:00
6c698c95be Refactor ReadEmailQuery to return structured response
Updated ReadEmailQuery to return a new response type,
ReadEmailQueryResponse, which includes both email data
and metadata (e.g., LastSync). Added the Account property
to ReadEmailQuery for specifying the email account.

Refactored ReadEmailQueryHandler to:
- Use IImapEmailService to fetch LastSync metadata.
- Return ReadEmailQueryResponse instead of a collection
  of ReceivedEmailDto.

Introduced ReadEmailQueryResponse class to encapsulate
LastSync and Emails properties.

Updated EmailController to handle the new response
structure, ensuring compatibility with the updated
ReadEmailQuery and its handler.
2026-08-17 01:13:14 +02:00
d01a0ceaa6 Refactor IMAP sync caching and improve thread safety
Replaced `IMemoryCache` with a thread-safe `ConcurrentDictionary`
for managing IMAP sync dates in `LimilabsImapEmailService`. Added
`GetLastImapSyncDate` and `SetLastImapSyncDate` methods to handle
cache operations. Updated the `IImapEmailService` interface to
include `GetLastImapSyncDate`. Simplified the `MarkAsSeenAsync`
method signature for better readability. Introduced a private
record type `ImapCacheKey` to encapsulate cache keys.
2026-08-14 08:40:56 +02:00
fd234618f7 chore: add legacy system analysis files for reference 2026-08-13 16:49:22 +02:00
f99bd8c399 fix(infrastructure): change IImapEmailService registration from Singleton to Scoped to support scoped DbContext dependency 2026-08-13 16:49:10 +02:00
c0bd391297 refactor(infrastructure): resolve IImapEmailService per-iteration from scoped DI in EmailSyncWorker; add structured logging and per-account error handling 2026-08-13 16:48:59 +02:00
cda70c8ced feat(infrastructure): replace DateFilter-based sync with IMemoryCache last-sync tracking in LimilabsImapEmailService; add CacheExtensions helper; return EmailSyncResult with processed/failed counts 2026-08-13 16:48:47 +02:00
578ecc7ba1 refactor(infrastructure): rename CreateAsync bulk overload to CreateRangeAsync and use AsNoTracking in ReceivedEmailRepository 2026-08-13 16:48:34 +02:00
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