| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- namespace SharedKernel;
- public sealed class AppSettings
- {
- public AppSection App { get; init; } = new();
- public ConnectionStringsSection ConnectionStrings { get; init; } = new();
- public RedisSection Redis { get; init; } = new();
- public SmtpSection SMTP { get; init; } = new();
- public JwtSection JWT { get; init; } = new();
- public ForwardedHeadersSection ForwardedHeaders { get; init; } = new();
- public CorsPolicySection CorsPolicy { get; init; } = new();
- public YouTubeSection YouTube { get; init; } = new();
- public BackgroundJobsSection BackgroundJobs { get; init; } = new();
- public EncryptionSection Encryption { get; init; } = new();
- public NextcloudTalkSection NextcloudTalk { get; init; } = new();
- public sealed class AppSection
- {
- public string Name { get; init; } = string.Empty;
- public string Company { get; init; } = string.Empty;
- public string BaseURL { get; init; } = string.Empty;
- public string ApiURL { get; init; } = string.Empty;
- public string FrontURL { get; init; } = string.Empty;
- }
- public sealed class ConnectionStringsSection
- {
- public string DefaultConnection { get; init; } = string.Empty;
- public int Timeout { get; init; }
- }
- public class RedisSection
- {
- public string DefaultConnection { get; init; } = string.Empty;
- public string CachePrefix { get; init; } = string.Empty;
- public string AuthTicketPrefix { get; init; } = string.Empty;
- public string DataProtectionKey { get; init; } = string.Empty;
- public TimeSpan DefaultKeyLifetime { get; init; }
- }
- public class SmtpSection
- {
- public string Host { get; init; } = default!;
- public int Port { get; init; } = 587;
- public string? User { get; init; }
- public string? Password { get; init; }
- public bool UseStartTls { get; init; } = true;
- public string FromEmail { get; init; } = default!;
- public string FromName { get; init; } = "no-reply";
- }
- public class JwtSection
- {
- public string SecretKey { get; init; } = string.Empty;
- public string Issuer { get; init; } = string.Empty;
- public string Audience { get; init; } = string.Empty;
- public int AccessTokenExpiration { get; init; }
- public int RefreshTokenExpiration { get; init; }
- }
- public class ForwardedHeadersSection
- {
- public int? ForwardLimit { get; init; } = default;
- public List<string> KnownProxies { get; init; } = [];
- public List<string> KnownNetworks { get; init; } = [];
- }
- public class CorsPolicySection
- {
- public string Name { get; init; } = string.Empty;
- public long PreflightMaxAgeSeconds { get; init; } = 0;
- public List<string> AllowedOrigins { get; init; } = [];
- }
- public class YouTubeSection
- {
- public string HubUrl { get; init; } = "https://pubsubhubbub.appspot.com/subscribe";
- public string CallbackUrl { get; init; } = string.Empty;
- public string HmacSecret { get; init; } = string.Empty;
- public int FeedPollingIntervalMinutes { get; init; } = 3;
- }
- public class BackgroundJobsSection
- {
- public bool LiveChat { get; init; } = true;
- public bool PubSubRenewal { get; init; } = true;
- public bool FeedPolling { get; init; } = true;
- public bool LiveViewerPoller { get; init; } = true;
- public bool ChannelCacheRefresh { get; init; } = true;
- public bool YouTubeDailyAggregator { get; init; } = true;
- public bool RankingDailyAggregator { get; init; } = true;
- public bool YouTubeStaleDataPurge { get; init; } = true;
- public bool ApiPurchaseConfirm { get; init; } = true;
- }
- /// <summary>
- /// Nextcloud Talk 운영 알림 — 봇 계정(Basic auth)으로 OCS Chat API 호출.
- /// POST {BaseUrl}/ocs/v2.php/apps/spreed/api/v1/chat/{roomToken}
- /// AlertRoomToken = 이상 징후 방 / ActivityRoomToken = API 사용 로그 방.
- /// 봇 계정은 두 방의 참가자여야 하며, AppPassword 는 Nextcloud 앱 비밀번호(또는 계정 비밀번호).
- /// </summary>
- public class NextcloudTalkSection
- {
- public bool Enabled { get; init; } = false;
- /// <summary>메시지 prefix 라벨 (예: Dev/Prod). dev·prod 배포가 둘 다 Production 환경명으로 돌므로 환경명 대신 사용. 비우면 EnvironmentName fallback.</summary>
- public string Label { get; init; } = string.Empty;
- public string BaseUrl { get; init; } = string.Empty;
- public string Username { get; init; } = string.Empty;
- public string AppPassword { get; init; } = string.Empty;
- public string AlertRoomToken { get; init; } = string.Empty;
- public string ActivityRoomToken { get; init; } = string.Empty;
- }
- /// <summary>
- /// 회원 PII(주소/연락처 등) 필드 암호화에 사용하는 AES-GCM 키 묶음.
- /// Keys 딕셔너리는 KeyVersion -> Base64(32바이트) 매핑. CurrentKeyVersion 은 신규 암호화에 사용할 버전.
- /// 키 회전 시 Keys 에 새 버전 추가 + CurrentKeyVersion 갱신. 복호화는 row 의 KeyVersion 컬럼으로 매핑하여 과거 키 사용.
- /// </summary>
- public class EncryptionSection
- {
- public int CurrentKeyVersion { get; init; } = 1;
- public Dictionary<string, string> Keys { get; init; } = new();
- }
- }
|