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.
118 lines
4.0 KiB
C#
118 lines
4.0 KiB
C#
using DigitalData.MessagingService.Application.EmailSending.Commands;
|
|
using DigitalData.MessagingService.Application.EmailReceiving.Queries;
|
|
using DigitalData.MessagingService.Application.EmailReceiving.Commands;
|
|
using DigitalData.MessagingService.Application.EmailAccount.Queries;
|
|
using DigitalData.MessagingService.Abstraction;
|
|
using MediatR;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace DigitalData.MessagingService.API.Controllers;
|
|
|
|
/// <summary>
|
|
/// Email sending API controller.
|
|
/// Enqueues outgoing emails to RabbitMQ for async processing.
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
public class EmailController(IMediator mediator) : ControllerBase
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public enum OnlyFilter
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
HtmlBody,
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
Uid,
|
|
}
|
|
|
|
#region Send
|
|
/// <summary>
|
|
/// Send an email, optionally with file attachments.
|
|
/// Omit the <c>attachments</c> field for a plain send.
|
|
/// </summary>
|
|
/// <param name="command">Email fields as form values</param>
|
|
/// <param name="attachments">Optional uploaded files</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>HTTP 202 Accepted with the queued event ID</returns>
|
|
[HttpPost]
|
|
[Consumes("multipart/form-data")]
|
|
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
public async Task<IActionResult> SendEmail(
|
|
[FromForm] PublishEmailCommand command,
|
|
IFormFileCollection? attachments,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var commandWithAttachments = command.WithAttachments(
|
|
await BuildAttachmentsAsync(attachments, cancellationToken));
|
|
|
|
var eventId = await mediator.Send(commandWithAttachments, cancellationToken);
|
|
return Accepted(new { Id = eventId });
|
|
}
|
|
|
|
private static async Task<IEnumerable<EmailAttachmentContext>> BuildAttachmentsAsync(
|
|
IFormFileCollection? files,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
if (files is null || files.Count == 0)
|
|
return [];
|
|
|
|
var result = new List<EmailAttachmentContext>(files.Count);
|
|
|
|
foreach (var file in files)
|
|
{
|
|
using var ms = new MemoryStream();
|
|
await file.CopyToAsync(ms, cancellationToken);
|
|
|
|
result.Add(new EmailAttachmentContext
|
|
{
|
|
FileName = file.FileName,
|
|
Content = ms.ToArray(),
|
|
ContentType = file.ContentType
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
#endregion Send
|
|
|
|
#region Receive
|
|
/// <summary>
|
|
/// Fetch emails from an IMAP mailbox.
|
|
/// </summary>
|
|
/// <param name="query">Query parameters for filtering and fetching emails from the IMAP mailbox.</param>
|
|
/// <param name="only"></param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>HTTP 200 with list of received emails.</returns>
|
|
[HttpGet]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> FetchEmails([FromQuery] FetchEmailsQuery query, [FromQuery] OnlyFilter? only = null, CancellationToken cancellationToken = default)
|
|
{
|
|
var emails = await mediator.Send(query, cancellationToken);
|
|
|
|
if(!emails.Any())
|
|
return NotFound("No emails found matching the specified criteria.");
|
|
|
|
if (only == OnlyFilter.HtmlBody)
|
|
{
|
|
if (emails.FirstOrDefault()?.HtmlBody is string htmlBody)
|
|
return Content(htmlBody, "text/html");
|
|
else
|
|
return NotFound();
|
|
}
|
|
else if (only == OnlyFilter.Uid)
|
|
return Ok(emails.Select(e => e.Uid).ToList());
|
|
else
|
|
return Ok(emails);
|
|
}
|
|
#endregion Receive
|
|
}
|