Skip to content

Commit 561178c

Browse files
committed
feat/integration gateway email fix
1 parent 3de72df commit 561178c

14 files changed

Lines changed: 53 additions & 32 deletions

File tree

backend/src/CCE.Api.External/appsettings.Development.json

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"RequireConfirmedEmail": false
6565
},
6666
"Email": {
67-
"Provider": "smtp",
67+
"Provider": "gateway",
6868
"Host": "localhost",
6969
"Port": 1025,
7070
"FromAddress": "no-reply@cce.local",
@@ -75,12 +75,8 @@
7575
},
7676
"ExternalApis": {
7777
"CommunicationGateway": {
78-
"BaseUrl": "https://gateway.example.com",
79-
"TimeoutSeconds": 30,
80-
"Auth": {
81-
"Type": "Bearer",
82-
"Token": "dev-gateway-token-change-me"
83-
}
78+
"BaseUrl": "http://localhost:3001",
79+
"TimeoutSeconds": 30
8480
}
8581
}
8682
}

backend/src/CCE.Api.External/appsettings.Production.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,19 @@
6464
"RequireConfirmedEmail": false
6565
},
6666
"Email": {
67-
"Provider": "smtp",
67+
"Provider": "gateway",
6868
"Host": "localhost",
6969
"Port": 1025,
7070
"FromAddress": "no-reply@cce.local",
7171
"FromName": "CCE Knowledge Center",
7272
"Username": "",
7373
"Password": "",
7474
"EnableSsl": false
75+
},
76+
"ExternalApis": {
77+
"CommunicationGateway": {
78+
"BaseUrl": "https://cce-mocks.bonto.run",
79+
"TimeoutSeconds": 30
80+
}
7581
}
7682
}

backend/src/CCE.Api.Internal/appsettings.Development.json

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"RequireConfirmedEmail": false
5252
},
5353
"Email": {
54-
"Provider": "smtp",
54+
"Provider": "gateway",
5555
"Host": "localhost",
5656
"Port": 1025,
5757
"FromAddress": "no-reply@cce.local",
@@ -62,12 +62,8 @@
6262
},
6363
"ExternalApis": {
6464
"CommunicationGateway": {
65-
"BaseUrl": "https://gateway.example.com",
66-
"TimeoutSeconds": 30,
67-
"Auth": {
68-
"Type": "Bearer",
69-
"Token": "dev-gateway-token-change-me"
70-
}
65+
"BaseUrl": "http://localhost:3001",
66+
"TimeoutSeconds": 30
7167
}
7268
}
7369
}

backend/src/CCE.Api.Internal/appsettings.Production.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,19 @@
5151
"RequireConfirmedEmail": false
5252
},
5353
"Email": {
54-
"Provider": "smtp",
54+
"Provider": "gateway",
5555
"Host": "localhost",
5656
"Port": 1025,
5757
"FromAddress": "no-reply@cce.local",
5858
"FromName": "CCE Knowledge Center",
5959
"Username": "",
6060
"Password": "",
6161
"EnableSsl": false
62+
},
63+
"ExternalApis": {
64+
"CommunicationGateway": {
65+
"BaseUrl": "https://cce-mocks.bonto.run",
66+
"TimeoutSeconds": 30
67+
}
6268
}
6369
}

backend/src/CCE.Application/Common/Interfaces/IEmailSender.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public interface IEmailSender
2929
/// <param name="to">Recipient address. Must be a valid RFC-5322 address.</param>
3030
/// <param name="subject">Subject line. Plain text; no formatting.</param>
3131
/// <param name="htmlBody">HTML body. Sanitized HTML allowed.</param>
32+
/// <param name="templateId">Optional gateway template identifier.</param>
3233
/// <param name="ct">Cancellation token.</param>
33-
Task SendAsync(string to, string subject, string htmlBody, CancellationToken ct = default);
34+
Task SendAsync(string to, string subject, string htmlBody, string? templateId = null, CancellationToken ct = default);
3435
}
Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using CCE.Application.Common.Interfaces;
2+
using CCE.Infrastructure.Email;
23
using CCE.Integration.Communication;
34
using Microsoft.Extensions.Logging;
5+
using Microsoft.Extensions.Options;
46

57
namespace CCE.Infrastructure.Communication;
68

@@ -11,20 +13,31 @@ namespace CCE.Infrastructure.Communication;
1113
public sealed class GatewayEmailSender : IEmailSender
1214
{
1315
private readonly ICommunicationGatewayClient _client;
16+
private readonly IOptions<EmailOptions> _options;
1417
private readonly ILogger<GatewayEmailSender> _logger;
1518

16-
public GatewayEmailSender(ICommunicationGatewayClient client, ILogger<GatewayEmailSender> logger)
19+
public GatewayEmailSender(
20+
ICommunicationGatewayClient client,
21+
IOptions<EmailOptions> options,
22+
ILogger<GatewayEmailSender> logger)
1723
{
1824
_client = client;
25+
_options = options;
1926
_logger = logger;
2027
}
2128

22-
public async Task SendAsync(string to, string subject, string htmlBody, CancellationToken ct = default)
29+
public async Task SendAsync(string to, string subject, string htmlBody, string? templateId = null, CancellationToken ct = default)
2330
{
24-
var request = new SendEmailRequest(to, subject, htmlBody);
31+
var request = new SendEmailRequest(
32+
To: to,
33+
From: _options.Value.FromAddress,
34+
Subject: subject,
35+
Html: htmlBody,
36+
TemplateId: templateId);
37+
2538
var response = await _client.SendEmailAsync(request, ct).ConfigureAwait(false);
2639

27-
if (!response.Success)
40+
if (!"success".Equals(response.Status, StringComparison.OrdinalIgnoreCase))
2841
{
2942
_logger.LogError(
3043
"Gateway email send failed for {To} with subject {Subject}: {Error}",
@@ -33,7 +46,7 @@ public async Task SendAsync(string to, string subject, string htmlBody, Cancella
3346
}
3447

3548
_logger.LogInformation(
36-
"Sent email via gateway to {To} with subject {Subject} (messageId {MessageId})",
37-
to, subject, response.MessageId);
49+
"Sent email via gateway to {To} with subject {Subject} (id {Id})",
50+
to, subject, response.Id);
3851
}
3952
}

backend/src/CCE.Infrastructure/Email/NullEmailSender.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public sealed class NullEmailSender : IEmailSender
1818

1919
public NullEmailSender(ILogger<NullEmailSender> logger) => _logger = logger;
2020

21-
public Task SendAsync(string to, string subject, string htmlBody, CancellationToken ct = default)
21+
public Task SendAsync(string to, string subject, string htmlBody, string? templateId = null, CancellationToken ct = default)
2222
{
2323
_logger.LogInformation(
2424
"[NullEmailSender] Would have sent email to {To} with subject {Subject} (body suppressed)",

backend/src/CCE.Infrastructure/Email/SmtpEmailSender.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public SmtpEmailSender(IOptions<EmailOptions> options, ILogger<SmtpEmailSender>
2323
_logger = logger;
2424
}
2525

26-
public async Task SendAsync(string to, string subject, string htmlBody, CancellationToken ct = default)
26+
public async Task SendAsync(string to, string subject, string htmlBody, string? templateId = null, CancellationToken ct = default)
2727
{
2828
var opts = _options.Value;
2929
using var message = new MimeMessage();

backend/src/CCE.Infrastructure/ExternalApis/ExternalApiServiceCollectionExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public static IServiceCollection AddExternalApiClient<TClient>(
2828
ContentSerializer = new SystemTextJsonContentSerializer(
2929
new System.Text.Json.JsonSerializerOptions
3030
{
31-
PropertyNameCaseInsensitive = true
31+
PropertyNameCaseInsensitive = true,
32+
PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase
3233
})
3334
};
3435

backend/src/CCE.Infrastructure/Identity/EntraIdRegistrationService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public async Task<RegistrationResult> CreateUserAsync(RegistrationRequest dto, C
103103
{
104104
var subject = "Welcome to CCE — your account is ready";
105105
var body = BuildWelcomeEmailHtml(dto, tempPassword);
106-
await _emailSender.SendAsync(created.UserPrincipalName!, subject, body, ct).ConfigureAwait(false);
106+
await _emailSender.SendAsync(created.UserPrincipalName!, subject, body, ct: ct).ConfigureAwait(false);
107107
}
108108
catch (Exception ex)
109109
{

0 commit comments

Comments
 (0)