AppSetting.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. namespace SharedKernel;
  2. public sealed class AppSettings
  3. {
  4. public AppSection App { get; init; } = new();
  5. public ConnectionStringsSection ConnectionStrings { get; init; } = new();
  6. public RedisSection Redis { get; init; } = new();
  7. public SmtpSection SMTP { get; init; } = new();
  8. public JwtSection JWT { get; init; } = new();
  9. public ForwardedHeadersSection ForwardedHeaders { get; init; } = new();
  10. public CorsPolicySection CorsPolicy { get; init; } = new();
  11. public YouTubeSection YouTube { get; init; } = new();
  12. public BackgroundJobsSection BackgroundJobs { get; init; } = new();
  13. public EncryptionSection Encryption { get; init; } = new();
  14. public FeaturesSection Features { get; init; } = new();
  15. public sealed class AppSection
  16. {
  17. public string Name { get; init; } = string.Empty;
  18. public string Company { get; init; } = string.Empty;
  19. public string BaseURL { get; init; } = string.Empty;
  20. public string ApiURL { get; init; } = string.Empty;
  21. public string FrontURL { get; init; } = string.Empty;
  22. }
  23. public sealed class ConnectionStringsSection
  24. {
  25. public string DefaultConnection { get; init; } = string.Empty;
  26. public int Timeout { get; init; }
  27. }
  28. public class RedisSection
  29. {
  30. public string DefaultConnection { get; init; } = string.Empty;
  31. public string CachePrefix { get; init; } = string.Empty;
  32. public string AuthTicketPrefix { get; init; } = string.Empty;
  33. public string DataProtectionKey { get; init; } = string.Empty;
  34. public TimeSpan DefaultKeyLifetime { get; init; }
  35. }
  36. public class SmtpSection
  37. {
  38. public string Host { get; init; } = default!;
  39. public int Port { get; init; } = 587;
  40. public string? User { get; init; }
  41. public string? Password { get; init; }
  42. public bool UseStartTls { get; init; } = true;
  43. public string FromEmail { get; init; } = default!;
  44. public string FromName { get; init; } = "no-reply";
  45. }
  46. public class JwtSection
  47. {
  48. public string SecretKey { get; init; } = string.Empty;
  49. public string Issuer { get; init; } = string.Empty;
  50. public string Audience { get; init; } = string.Empty;
  51. public int AccessTokenExpiration { get; init; }
  52. public int RefreshTokenExpiration { get; init; }
  53. }
  54. public class ForwardedHeadersSection
  55. {
  56. public int? ForwardLimit { get; init; } = default;
  57. public List<string> KnownProxies { get; init; } = [];
  58. public List<string> KnownNetworks { get; init; } = [];
  59. }
  60. public class CorsPolicySection
  61. {
  62. public string Name { get; init; } = string.Empty;
  63. public long PreflightMaxAgeSeconds { get; init; } = 0;
  64. public List<string> AllowedOrigins { get; init; } = [];
  65. }
  66. public class YouTubeSection
  67. {
  68. public string HubUrl { get; init; } = "https://pubsubhubbub.appspot.com/subscribe";
  69. public string CallbackUrl { get; init; } = string.Empty;
  70. public string HmacSecret { get; init; } = string.Empty;
  71. public int FeedPollingIntervalMinutes { get; init; } = 3;
  72. }
  73. public class BackgroundJobsSection
  74. {
  75. public bool LiveChat { get; init; } = true;
  76. public bool PubSubRenewal { get; init; } = true;
  77. public bool FeedPolling { get; init; } = true;
  78. public bool LiveViewerPoller { get; init; } = true;
  79. public bool ChannelCacheRefresh { get; init; } = true;
  80. public bool YouTubeDailyAggregator { get; init; } = true;
  81. public bool YouTubeStaleDataPurge { get; init; } = true;
  82. }
  83. /// <summary>
  84. /// 기능 단위 활성화 플래그. 코드/스키마는 보존하고 노출만 차단하는 soft-off 스위치.
  85. /// Channel=false 시 채널/스튜디오/YouTube 관련 API 와 백그라운드 서비스 전체 비활성 (기본 false).
  86. /// </summary>
  87. public class FeaturesSection
  88. {
  89. public bool Channel { get; init; } = false;
  90. }
  91. /// <summary>
  92. /// 회원 PII(주소/연락처 등) 필드 암호화에 사용하는 AES-GCM 키 묶음.
  93. /// Keys 딕셔너리는 KeyVersion -> Base64(32바이트) 매핑. CurrentKeyVersion 은 신규 암호화에 사용할 버전.
  94. /// 키 회전 시 Keys 에 새 버전 추가 + CurrentKeyVersion 갱신. 복호화는 row 의 KeyVersion 컬럼으로 매핑하여 과거 키 사용.
  95. /// </summary>
  96. public class EncryptionSection
  97. {
  98. public int CurrentKeyVersion { get; init; } = 1;
  99. public Dictionary<string, string> Keys { get; init; } = new();
  100. }
  101. }