namespace SQLInsight.Hub; public sealed class HubServerOptions { public const string SectionName = "SQLInsight:Hub"; /// Public keys trusted for licenses in addition to the embedded ones (key id → base64 SubjectPublicKeyInfo). public IDictionary TrustedKeys { get; } = new Dictionary(); /// Largest accepted request body. public long MaxRequestBytes { get; set; } = 5 * 1024 * 1024; /// Most findings accepted per submission. public int MaxFindingsPerSubmission { get; set; } = 2000; /// Portal login attempts allowed per client IP per minute. public int LoginAttemptsPerMinute { get; set; } = 10; /// /// Folder with the signed update feed (made with the vendor tool's publish command), served at /updates/. /// Empty: the hub does not serve updates. /// public string? UpdateFeedPath { get; set; } /// /// Folder for the keys that protect login cookies and form tokens. Set it (and keep it) when running in a container /// or on more than one server; otherwise staff are logged out on every restart. /// public string? DataProtectionKeysPath { get; set; } /// /// IP addresses of reverse proxies in front of the hub. Their X-Forwarded-For/-Proto headers are trusted, so login /// rate limiting sees the real client address. /// public IList KnownProxies { get; } = []; public RetentionOptions Retention { get; set; } = new(); /// Upgrade insights shared with agents (aggregated, anonymous). public Insights.InsightOptions Insights { get; set; } = new(); } /// How long the hub keeps data it no longer needs. Applied once a day. public sealed class RetentionOptions { /// Resolved findings are deleted this long after they were resolved (unless linked to an open support case). public TimeSpan ResolvedFindings { get; set; } = TimeSpan.FromDays(365); /// The submission log (when what was received) is deleted after this. public TimeSpan Submissions { get; set; } = TimeSpan.FromDays(90); /// Instances that have not reported for this long are deleted with their findings. public TimeSpan SilentInstances { get; set; } = TimeSpan.FromDays(180); }