| | | 1 | | using Microsoft.Extensions.Configuration; |
| | | 2 | | using Microsoft.Extensions.Hosting; |
| | | 3 | | using Microsoft.Extensions.Logging; |
| | | 4 | | using Microsoft.Extensions.Options; |
| | | 5 | | using Newtonsoft.Json; |
| | | 6 | | using Newtonsoft.Json.Linq; |
| | | 7 | | |
| | | 8 | | namespace Services.EmailRoutingServices; |
| | | 9 | | |
| | | 10 | | public interface IImapSettingsStore |
| | | 11 | | { |
| | | 12 | | ImapSettings GetCurrent(); |
| | | 13 | | ImapSettings MergeWithCurrent(EmailImapSettingsInput input); |
| | | 14 | | Task SaveAsync(EmailImapSettingsInput input, CancellationToken cancellationToken = default); |
| | | 15 | | } |
| | | 16 | | |
| | | 17 | | public class EmailImapSettingsInput |
| | | 18 | | { |
| | 15 | 19 | | public string Host { get; set; } = string.Empty; |
| | 15 | 20 | | public int Port { get; set; } = 993; |
| | 15 | 21 | | public string UserName { get; set; } = string.Empty; |
| | 13 | 22 | | public string? Password { get; set; } |
| | 15 | 23 | | public bool UseSsl { get; set; } = true; |
| | 16 | 24 | | public string Folder { get; set; } = "INBOX"; |
| | 15 | 25 | | public int FetchLimit { get; set; } = 20; |
| | | 26 | | } |
| | | 27 | | |
| | | 28 | | public class FileImapSettingsStore : IImapSettingsStore |
| | | 29 | | { |
| | | 30 | | private readonly IHostEnvironment _environment; |
| | | 31 | | private readonly IConfiguration _configuration; |
| | | 32 | | private readonly IOptionsMonitor<ImapSettings> _settingsMonitor; |
| | | 33 | | private readonly ILogger<FileImapSettingsStore> _logger; |
| | | 34 | | |
| | | 35 | | public FileImapSettingsStore( |
| | | 36 | | IHostEnvironment environment, |
| | | 37 | | IConfiguration configuration, |
| | | 38 | | IOptionsMonitor<ImapSettings> settingsMonitor, |
| | | 39 | | ILogger<FileImapSettingsStore> logger) |
| | | 40 | | { |
| | | 41 | | _environment = environment; |
| | | 42 | | _configuration = configuration; |
| | | 43 | | _settingsMonitor = settingsMonitor; |
| | | 44 | | _logger = logger; |
| | | 45 | | } |
| | | 46 | | |
| | | 47 | | public ImapSettings GetCurrent() => _settingsMonitor.CurrentValue; |
| | | 48 | | |
| | | 49 | | public ImapSettings MergeWithCurrent(EmailImapSettingsInput input) |
| | | 50 | | { |
| | | 51 | | var current = GetCurrent(); |
| | | 52 | | return new ImapSettings |
| | | 53 | | { |
| | | 54 | | Host = input.Host.Trim(), |
| | | 55 | | Port = input.Port, |
| | | 56 | | UserName = input.UserName.Trim(), |
| | | 57 | | Password = string.IsNullOrWhiteSpace(input.Password) ? current.Password : input.Password, |
| | | 58 | | UseSsl = input.UseSsl, |
| | | 59 | | Folder = string.IsNullOrWhiteSpace(input.Folder) ? "INBOX" : input.Folder.Trim(), |
| | | 60 | | FetchLimit = input.FetchLimit, |
| | | 61 | | FetchScanLimit = current.FetchScanLimit, |
| | | 62 | | FetchWindowDays = current.FetchWindowDays, |
| | | 63 | | FetchAfterUtc = current.FetchAfterUtc |
| | | 64 | | }; |
| | | 65 | | } |
| | | 66 | | |
| | | 67 | | public async Task SaveAsync(EmailImapSettingsInput input, CancellationToken cancellationToken = default) |
| | | 68 | | { |
| | | 69 | | var merged = MergeWithCurrent(input); |
| | | 70 | | var configPath = AppRuntimeSettingsPaths.ResolvePath(_environment.ContentRootPath, _configuration); |
| | | 71 | | await AppRuntimeSettingsWriter.SaveAsync( |
| | | 72 | | _environment.ContentRootPath, |
| | | 73 | | _configuration, |
| | | 74 | | root => |
| | | 75 | | { |
| | | 76 | | root["ImapSettings"] = JObject.FromObject(merged, JsonSerializer.Create(new JsonSerializerSettings |
| | | 77 | | { |
| | | 78 | | NullValueHandling = NullValueHandling.Ignore |
| | | 79 | | })); |
| | | 80 | | }, |
| | | 81 | | cancellationToken); |
| | | 82 | | |
| | | 83 | | _logger.LogInformation("ImapSettings saved to {ConfigPath} for mailbox {UserName}", configPath, merged.UserName) |
| | | 84 | | } |
| | | 85 | | } |