Платформенные настройки: один row, не tenant-scoped, видны и меняются только Супер-администратором. Хранят SMTP-креды для исходящей почты (forgot-password, нотификации). IMAP к этому отношения не имеет — IMAP для чтения входящей, нам нужен SMTP. Поля: - SmtpHost, SmtpPort - SmtpUseSsl (implicit TLS / 465) и SmtpStartTls (587, по дефолту true) - SmtpUsername, SmtpPasswordEncrypted (хранится зашифрованным через DataProtection API; в API-ответах не выходит, только has-password флаг) - FromEmail, FromName Миграция Phase5b_PlatformSettings создаёт таблицу public.platform_settings. Конфиг EF в AppDbContext: HasMaxLength для строк.
37 lines
2 KiB
C#
37 lines
2 KiB
C#
using foodmarket.Domain.Common;
|
||
|
||
namespace foodmarket.Domain.Platform;
|
||
|
||
/// <summary>Платформенные настройки (singleton, single-row). Хранят SMTP-креды
|
||
/// для отправки писем (forgot-password, инвайты, нотификации). Не tenant-scoped —
|
||
/// общий конфиг для всей платформы, видны и меняются только Супер-администратором.
|
||
///
|
||
/// SmtpPassword хранится зашифрованным через DataProtection API
|
||
/// (`IDataProtectionProvider.CreateProtector("foodmarket.smtp")`); снаружи
|
||
/// (контроллер) — никогда не возвращается в открытом виде, только has-password флаг.</summary>
|
||
public class PlatformSettings : Entity
|
||
{
|
||
/// <summary>SMTP-сервер для отправки исходящей почты (НЕ IMAP — IMAP это
|
||
/// для чтения входящей).</summary>
|
||
public string? SmtpHost { get; set; }
|
||
public int? SmtpPort { get; set; }
|
||
|
||
/// <summary>Implicit TLS (SMTPS, обычно порт 465). Взаимоисключающий
|
||
/// со SmtpStartTls (587).</summary>
|
||
public bool SmtpUseSsl { get; set; }
|
||
|
||
/// <summary>STARTTLS upgrade (обычно порт 587). По дефолту true в большинстве
|
||
/// современных провайдеров (Gmail/Yandex/Mailgun).</summary>
|
||
public bool SmtpStartTls { get; set; } = true;
|
||
|
||
public string? SmtpUsername { get; set; }
|
||
|
||
/// <summary>Зашифрованный SmtpPassword (base64 через DataProtection).
|
||
/// Никогда не отдаётся в API-ответах. Установка только через PUT с
|
||
/// явно переданным new-password полем.</summary>
|
||
public string? SmtpPasswordEncrypted { get; set; }
|
||
|
||
public string? FromEmail { get; set; }
|
||
public string? FromName { get; set; }
|
||
}
|