Harden notifications: bump MailKit, bound webhook body, share truncation, skip soft-deleted members
This commit is contained in:
@@ -33,6 +33,7 @@ public sealed class LineWebhookController : ControllerBase
|
||||
}
|
||||
|
||||
[HttpPost("webhook")]
|
||||
[RequestSizeLimit(262_144)]
|
||||
public async Task<IActionResult> Webhook(CancellationToken ct)
|
||||
{
|
||||
using var reader = new StreamReader(Request.Body, Encoding.UTF8);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
Provides DevExpress.Drawing.v24.1.Skia.dll; without it RichEditDocumentServer
|
||||
throws DllNotFoundException at runtime on Linux (Windows falls back to GDI+). -->
|
||||
<PackageReference Include="DevExpress.Drawing.Skia" Version="24.1.3" />
|
||||
<PackageReference Include="MailKit" Version="4.8.0" />
|
||||
<PackageReference Include="MailKit" Version="4.17.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.11" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.11" />
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace ROLAC.API.Services.Notifications;
|
||||
/// </summary>
|
||||
public sealed class EmailService : IEmailService
|
||||
{
|
||||
private const int BodyLogMaxLength = 8000;
|
||||
|
||||
private readonly AppDbContext _db;
|
||||
private readonly ISmtpDispatcher _dispatcher;
|
||||
private readonly CurrentUserAccessor _currentUser;
|
||||
@@ -44,7 +42,7 @@ public sealed class EmailService : IEmailService
|
||||
TargetExternalId = recipient.Address,
|
||||
Subject = message.Subject,
|
||||
MemberId = recipient.MemberId,
|
||||
Body = Truncate(message.HtmlBody),
|
||||
Body = NotificationLogText.Truncate(message.HtmlBody),
|
||||
SentByUserId = sentBy,
|
||||
SentAt = DateTime.UtcNow,
|
||||
};
|
||||
@@ -97,6 +95,4 @@ public sealed class EmailService : IEmailService
|
||||
return resolved;
|
||||
}
|
||||
|
||||
private static string Truncate(string body) =>
|
||||
body.Length <= BodyLogMaxLength ? body : body[..BodyLogMaxLength] + "…[truncated]";
|
||||
}
|
||||
|
||||
@@ -31,8 +31,12 @@ public sealed class LineNotificationService : ILineNotificationService
|
||||
var failures = new List<NotificationFailure>();
|
||||
var sentCount = 0;
|
||||
|
||||
var liveMemberIds = await _db.Members
|
||||
.Where(m => memberIds.Contains(m.Id))
|
||||
.Select(m => m.Id)
|
||||
.ToListAsync(ct);
|
||||
var bindings = await _db.MemberChannelBindings
|
||||
.Where(b => b.Channel == Channel && memberIds.Contains(b.MemberId))
|
||||
.Where(b => b.Channel == Channel && liveMemberIds.Contains(b.MemberId))
|
||||
.ToListAsync(ct);
|
||||
foreach (var binding in bindings)
|
||||
{
|
||||
@@ -146,7 +150,7 @@ public sealed class LineNotificationService : ILineNotificationService
|
||||
TargetExternalId = externalId,
|
||||
MemberId = memberId,
|
||||
MessagingGroupId = groupId,
|
||||
Body = body,
|
||||
Body = NotificationLogText.Truncate(body),
|
||||
Status = result.Success ? NotificationStatuses.Sent : NotificationStatuses.Failed,
|
||||
Error = result.Error,
|
||||
SentByUserId = sentBy,
|
||||
|
||||
@@ -47,3 +47,13 @@ public sealed record EmailMessage(
|
||||
string HtmlBody,
|
||||
IReadOnlyList<EmailAttachment>? Attachments = null,
|
||||
string? SentByUserId = null);
|
||||
|
||||
/// <summary>Helpers for building NotificationLog rows consistently across channels.</summary>
|
||||
public static class NotificationLogText
|
||||
{
|
||||
public const int BodyMaxLength = 8000;
|
||||
|
||||
/// <summary>Caps a body string so an oversized message can't bloat the log table.</summary>
|
||||
public static string Truncate(string body) =>
|
||||
body.Length <= BodyMaxLength ? body : body[..BodyMaxLength] + "…[truncated]";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user