refactor(api): inject IEmailSyncService into SyncController; change OAuth2 authorize route to username param; add Swagger UI metadata and description links
This commit is contained in:
@@ -20,20 +20,20 @@ public class OAuth2Controller(IMediator mediator, IHttpContextAccessor httpConte
|
||||
/// Step 1: Redirects the user to Google's consent screen for the specified email account.
|
||||
/// After consent, Google redirects to <c>/api/oauth2/google/callback</c> with an authorization code.
|
||||
/// </summary>
|
||||
/// <param name="accountId">ID of the email account to authorize.</param>
|
||||
/// <param name="username">the email account to authorize.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>HTTP 302 redirect to Google consent screen.</returns>
|
||||
[HttpGet("google/authorize/{accountId:int}")]
|
||||
[HttpGet("google/authorize/{username}")]
|
||||
[ProducesResponseType(StatusCodes.Status302Found)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> AuthorizeGoogle(int accountId, CancellationToken cancellationToken)
|
||||
public async Task<IActionResult> AuthorizeGoogle([FromRoute] string username, CancellationToken cancellationToken)
|
||||
{
|
||||
var redirectUri = BuildCallbackUri();
|
||||
|
||||
var authUrl = await mediator.Send(new GetOAuth2AuthorizationUrlQuery
|
||||
{
|
||||
AccountId = accountId,
|
||||
Username = username,
|
||||
RedirectUri = redirectUri
|
||||
}, cancellationToken);
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using DigitalData.MessagingService.Infrastructure.Services.Background;
|
||||
using DigitalData.MessagingService.Application.Common.Interfaces;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace DigitalData.MessagingService.API.Controllers;
|
||||
|
||||
@@ -9,7 +8,7 @@ namespace DigitalData.MessagingService.API.Controllers;
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class SyncController(IEnumerable<IHostedService> hostedServices) : ControllerBase
|
||||
public class SyncController(IEmailSyncService emailSyncService) : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Triggers an immediate email sync cycle for all configured accounts,
|
||||
@@ -22,14 +21,7 @@ public class SyncController(IEnumerable<IHostedService> hostedServices) : Contro
|
||||
[ProducesResponseType(StatusCodes.Status503ServiceUnavailable)]
|
||||
public IActionResult TriggerSync()
|
||||
{
|
||||
var syncWorker = hostedServices.OfType<EmailSyncWorker>().FirstOrDefault();
|
||||
|
||||
if (syncWorker is null)
|
||||
return StatusCode(StatusCodes.Status503ServiceUnavailable,
|
||||
new { Message = "EmailSyncWorker is not running." });
|
||||
|
||||
syncWorker.TriggerSync();
|
||||
|
||||
return Accepted(new { Message = "Sync triggered. The next cycle will start immediately." });
|
||||
var syncTime = emailSyncService.ForceTriggerSync();
|
||||
return Accepted(new { syncTime });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,35 @@ try
|
||||
builder.Services.AddControllers();
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
builder.Services.AddSwaggerGen(options =>
|
||||
{
|
||||
options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
|
||||
{
|
||||
Title = "DigitalData MessagingService API",
|
||||
Version = "v1",
|
||||
Description = """
|
||||
Die **DigitalData MessagingService API** stellt Endpunkte zur Verwaltung von E-Mail-Konten,
|
||||
E-Mail-Profilen sowie zur Verarbeitung und Nachverfolgung eingehender und ausgehender Nachrichten bereit.
|
||||
|
||||
---
|
||||
|
||||
## Authentifizierung
|
||||
|
||||
Für OAuth2-geschützte Endpunkte ist eine Authentifizierung erforderlich.
|
||||
Rufen Sie den folgenden Endpunkt auf und ersetzen Sie `{E-Mail-Adresse}` durch die zu authentifizierende E-Mail-Adresse:
|
||||
|
||||
`/api/OAuth2/google/authorize/{E-Mail-Adresse}`
|
||||
|
||||
**Beispiel:** **[/api/OAuth2/google/authorize/htek0100@gmail.com →](/api/OAuth2/google/authorize/htek0100@gmail.com)**
|
||||
|
||||
---
|
||||
|
||||
## Weiterführende Links
|
||||
|
||||
- [Serilog Log-Viewer ↗](/serilog-ui)
|
||||
"""
|
||||
});
|
||||
});
|
||||
|
||||
// Required by OAuth2Controller to build callback URIs
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
@@ -92,14 +120,30 @@ try
|
||||
// Add Serilog request logging
|
||||
app.UseSerilogRequestLogging();
|
||||
|
||||
// Configure Swagger — enabled in Development always, and in other environments based on appsettings
|
||||
// Configure Swagger <EFBFBD> enabled in Development always, and in other environments based on appsettings
|
||||
var swaggerEnabled = app.Environment.IsDevelopment()
|
||||
|| app.Configuration.GetValue<bool>("Swagger:Enabled");
|
||||
|
||||
if (swaggerEnabled)
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
app.UseSwaggerUI(ui =>
|
||||
{
|
||||
ui.SwaggerEndpoint("/swagger/v1/swagger.json", "DigitalData MessagingService API v1");
|
||||
// Inject CSS so all description links open in a new tab
|
||||
ui.InjectStylesheet("data:text/css,.renderedMarkdown a{target:_blank}");
|
||||
ui.InjectJavascript("data:text/javascript," + Uri.EscapeDataString("""
|
||||
window.addEventListener('load', () => {
|
||||
const observer = new MutationObserver(() => {
|
||||
document.querySelectorAll('.renderedMarkdown a').forEach(a => {
|
||||
a.setAttribute('target', '_blank');
|
||||
a.setAttribute('rel', 'noopener noreferrer');
|
||||
});
|
||||
});
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
});
|
||||
"""));
|
||||
});
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
Reference in New Issue
Block a user