99 lines
2.9 KiB
C#
99 lines
2.9 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Options;
|
|
using ROLAC.API.Data;
|
|
|
|
namespace ROLAC.API.Services.Notifications;
|
|
|
|
/// <summary>
|
|
/// Supplies the current SMTP/Line settings from the <c>NotificationSetting</c> singleton row,
|
|
/// caching a snapshot in memory so send paths don't hit the DB on every message. Registered as a
|
|
/// singleton; the Settings UI calls <see cref="Reload"/> after an edit so changes take effect
|
|
/// without restarting the API. Falls back to the "Smtp"/"Line" appsettings sections if the row
|
|
/// has not been seeded yet.
|
|
/// </summary>
|
|
public interface INotificationSettingsService
|
|
{
|
|
SmtpOptions GetSmtp();
|
|
LineOptions GetLine();
|
|
void Reload();
|
|
}
|
|
|
|
public sealed class NotificationSettingsService : INotificationSettingsService
|
|
{
|
|
private readonly IServiceScopeFactory _scopeFactory;
|
|
private readonly IOptions<SmtpOptions> _smtpFallback;
|
|
private readonly IOptions<LineOptions> _lineFallback;
|
|
private readonly object _gate = new();
|
|
|
|
private SmtpOptions? _smtp;
|
|
private LineOptions? _line;
|
|
|
|
public NotificationSettingsService(
|
|
IServiceScopeFactory scopeFactory,
|
|
IOptions<SmtpOptions> smtpFallback,
|
|
IOptions<LineOptions> lineFallback)
|
|
{
|
|
_scopeFactory = scopeFactory;
|
|
_smtpFallback = smtpFallback;
|
|
_lineFallback = lineFallback;
|
|
}
|
|
|
|
public SmtpOptions GetSmtp()
|
|
{
|
|
EnsureLoaded();
|
|
return _smtp!;
|
|
}
|
|
|
|
public LineOptions GetLine()
|
|
{
|
|
EnsureLoaded();
|
|
return _line!;
|
|
}
|
|
|
|
public void Reload()
|
|
{
|
|
lock (_gate)
|
|
{
|
|
_smtp = null;
|
|
_line = null;
|
|
}
|
|
}
|
|
|
|
private void EnsureLoaded()
|
|
{
|
|
lock (_gate)
|
|
{
|
|
if (_smtp is not null && _line is not null)
|
|
return;
|
|
|
|
using var scope = _scopeFactory.CreateScope();
|
|
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
|
var row = db.NotificationSettings.AsNoTracking().OrderBy(s => s.Id).FirstOrDefault();
|
|
|
|
if (row is null)
|
|
{
|
|
// Not seeded yet — use the appsettings values so sends still work.
|
|
_smtp = _smtpFallback.Value;
|
|
_line = _lineFallback.Value;
|
|
return;
|
|
}
|
|
|
|
_smtp = new SmtpOptions
|
|
{
|
|
Host = row.SmtpHost,
|
|
Port = row.SmtpPort,
|
|
UseSsl = row.SmtpUseSsl,
|
|
User = row.SmtpUser,
|
|
Password = row.SmtpPassword,
|
|
FromAddress = row.FromAddress,
|
|
FromName = row.FromName,
|
|
};
|
|
_line = new LineOptions
|
|
{
|
|
ChannelAccessToken = row.LineChannelAccessToken,
|
|
ChannelSecret = row.LineChannelSecret,
|
|
};
|
|
}
|
|
}
|
|
}
|