This commit is contained in:
HueByte
2026-07-23 09:48:40 +00:00
parent 37bd8c0f57
commit 32c664518a
144 changed files with 5098 additions and 6498 deletions
@@ -8,4 +8,11 @@ public sealed class ServerLogsOptions
```
Live server-log room configuration is encapsulated by this strongly-typed options class. It binds to the ServerLogs config section and supports environment overrides, controlling whether the live streaming channel is created and who can view it. When Enabled is true, a read-only system channel is auto-created and log events are streamed in real time; log lines themselves are not stored as messages in the database, with persistence remaining in the rolling Serilog log files.
`ServerLogsOptions` is a configuration model that binds to the `ServerLogs` configuration section (and supports environment overrides via keys like `ServerLogs__Enabled`). When `Enabled` is true, the system automatically creates a read-only system channel named from `RoomName` (default `server-logs`) and streams log events to that channel in real time; log lines are never persisted as messages in the database, with persistence limited to the rolling `Serilog` log files. It exposes several tunables: `RoomName` sets the auto-created channel name and must satisfy the normal channel-name rules; the name is reserved so users cannot create a channel with it. `MinRole` defines the minimum server role that can see and join the log room (default `ServerRole.Mod`); `MinLevel` selects the minimum log event level to stream (default `LogEventLevel.Information`); `BacklogLines` controls how many recent log entries are replayed from the log files when the room is opened (default 100); `LogDirectory` and `LogFilePattern` point to where the rolling log files live and how they are named (defaults `logs` and `echohub-server-*.log`). The derived `NormalizedRoomName` provides a lowercased, trimmed variant of `RoomName` for comparisons.
## Remarks
The `ServerLogsOptions` abstraction centralizes live-log streaming behind a configuration object, separating real-time visibility from persistent message storage. It ensures a consistent, auto-created channel for server logs (named by `RoomName`, default `server-logs`) and uses `MinRole`/`MinLevel` to control who and what they can see, without requiring code changes to enable the feature. The `NormalizedRoomName` aids robust comparisons elsewhere in the system.
## Notes
- Live-streaming may expose sensitive information; ensure `MinRole` and `MinLevel` align with privacy expectations.
- Backlog replay relies on the Serilog file sink configuration; ensure `LogDirectory` exists and matches `LogFilePattern`.
@@ -8,12 +8,30 @@ public sealed class SpamOptions
```
SpamOptions is a configuration object that encapsulates the anti-spam thresholds used by the server. It is bound from the Spam config section and exposes the toggles and numeric limits that govern how the system enforces per-user rate limits, duplicate message handling, auto-muting behavior, and the protections around first-time channel joins and channel creation. The defaults are intentionally lenient so a fast typist wont trip them, and moderators (and above) are exempt from these protections. Use this class to adjust spam-protection policy without changing code.
SpamOptions is a configuration class bound to the 'Spam' config section that stores all anti-spam thresholds. It centralizes rate limits, duplicate suppression, auto-mute behavior, and onboarding quotas so enforcement logic can apply consistent rules; adjust these values here rather than hard-coding them throughout.
## Remarks
SpamOptions centralizes policy decisions for anti-spam enforcement, serving as a single source of truth for the thresholds consumed by the spam protection subsystem. By binding to configuration, it keeps rules out of hard-coded logic and enables runtime tuning via the Spam section. The design separates concerns across rate limiting (per-user messages), duplicate detection, auto-mute behavior, and early channel-join/channel-create protections, making it easier to tune each facet without collateral impact. The auto-mute behavior ties into the existing moderation tooling (MuteExpirationService), illustrating cohesive behavior with the broader user-suspension lifecycle. The note about end-to-end encrypted rooms clarifies that identical plaintext can yield different ciphertext, so the duplicate-detection rule may not apply in those contexts.
SpamOptions acts as the configuration contract for anti-spam behavior. It centralizes all thresholds so the enforcement and moderation subsystems can apply consistent rules without hard-coded values scattered through the codebase. It coordinates rate limiting, duplicate suppression, auto-mute behavior, and first-join/channel-creation limits via a single, testable object that can be configured at startup.
## Example
```csharp
var options = new SpamOptions
{
Enabled = true,
MaxMessagesPerWindow = 12,
WindowSeconds = 10,
MaxDuplicateMessages = 2,
AutoMuteMinutes = 10,
ViolationThreshold = 6,
ViolationWindowMinutes = 3,
MaxJoinsPerWindow = 30,
JoinWindowSeconds = 20,
MaxChannelCreatesPerWindow = 2,
ChannelCreateWindowMinutes = 15
};
```
## Notes
- Auto-mute is controlled by AutoMuteMinutes. Setting AutoMuteMinutes to 0 disables auto-mute (rejections still apply if thresholds are reached).
- MaxMessagesPerWindow and WindowSeconds govern per-user message rate; adjust them with awareness of your typical user pacing to avoid false positives.
- MaxJoinsPerWindow and JoinWindowSeconds apply to first-time channel joins; joins to channels the user already belongs to do not count toward the limit, ensuring normal reconnects dont trigger protections.
- Auto-mute is disabled when `AutoMuteMinutes` is 0; rejections still apply.
- The first-join burst behavior relies on `MaxJoinsPerWindow` being large enough for your public channel count.
- These values are loaded from the config and may be adjusted to balance user experience against protection needs.
@@ -8,12 +8,7 @@ public sealed class StatsOptions
```
StatsOptions is a bound configuration object that governs the periodic server-stats reporter. When Enabled is true, a background job periodically snapshots server activity, logs the snapshot as pretty-printed JSON, and persists it to the database; IntervalHours controls cadence, and RetentionDays controls how long reports are kept. The environment override Stats__Enabled allows turning the reporter on or off via environment configuration without changing code.
StatsOptions is a configuration-bound class that governs the periodic server-stats reporting behavior of the application. It binds from the Stats config section (with environment overrides like Stats__Enabled) and, when Enabled is true, drives a background job that periodically snapshots server activity, logs the snapshot as pretty-printed JSON, and persists it to the database. Developers would adjust IntervalHours to change how often reports are generated and RetentionDays to control how long reports are kept, or toggle Enabled to enable/disable the reporting; defaults are Enabled = true, IntervalHours = 6, and RetentionDays = 90.
## Remarks
StatsOptions serves as a simple, sealed data contract that the configuration system binds to at startup, providing a single source of truth for the reporter settings. Centralizing these knobs here avoids scattering config keys throughout the code and makes it easy to swap configuration providers or add validation in one place. The defaults (Enabled = true, IntervalHours = 6, RetentionDays = 90) define the out-of-the-box behavior and can be overridden by environment or configuration.
## Notes
- RetentionDays: 0 means keep reports indefinitely; any positive number prunes older entries.
- IntervalHours is a double; fractional values (e.g., 1.5) are allowed, but scheduling resolution depends on the hosting environment.
- Enabled acts as the master switch for the background job; disabling it stops snapshots until re-enabled.
This class serves as the configuration object consumed by the background stats collection service, isolating configuration from implementation and enabling the Stats job to be controlled entirely via config.
@@ -8,24 +8,21 @@ public sealed class UploadLimits
```
UploadLimits is a configuration-bound value object that centralizes the admin-defined upload size caps. It reads sizes in megabytes from the Uploads configuration and exposes corresponding byte-sized properties used during enforcement. When the Uploads section is missing or incomplete, the defaults mirror HubConstants to preserve the historical built-in limits.
UploadLimits provides the admin-configurable ceilings for uploads, bound from the `Uploads` configuration section and converted to bytes for enforcement. Values are expressed in megabytes in configuration and exposed as byte-based properties for the enforcement layer; if the `Uploads` section is absent or partial, defaults mirror [`HubConstants`](../../EchoHub.Core/Constants/HubConstants.cs.md) to preserve historical limits.
The class exposes MB-based properties for each category (MaxFileSizeMB, MaxImageSizeMB, MaxAudioSizeMB, MaxAvatarSizeMB) and a per-message attachment cap (MaxAttachmentsPerMessage). It also exposes computed byte-based counterparts (MaxFileSizeBytes, MaxImageSizeBytes, MaxAudioSizeBytes, MaxAvatarSizeBytes) derived from the MB properties. The per-kind limit is exposed via `MaxForKind(AttachmentKind)`, which returns the corresponding byte limit for images, audio, or the general file size for other kinds. Finally, `MaxRequestBodyBytes` represents the absolute ceiling for a single message request body, calculated as `MaxFileSizeBytes * MaxAttachmentsPerMessage`, ensuring that increased configuration actually scales the request payload footprint.
## Remarks
UploadLimits centralizes the policy governing uploads (files, images, audio, avatars) and the maximum number of attachments per message. The MB-based properties feed their byte-sized counterparts (MaxFileSizeBytes, MaxImageSizeBytes, etc.) for enforcement. MaxForKind provides a per-kind ceiling, while MaxRequestBodyBytes computes the overall request-body cap (largest file size multiplied by the attachment limit) to ensure configuration changes actually take effect at the HTTP boundary.
UploadLimits serves as a focused bridge between configuration and enforcement. By centralizing unit conversion (MB to bytes) and collating per-kind and per-message constraints, it reduces the risk of inconsistent bounds across the upload pipeline and makes it straightforward to adjust limits in one place. The design anticipates future extension to additional attachment kinds without altering enforcement sites, while preserving backward-compatible defaults when the configuration is incomplete.
## Example
```csharp
var limits = new UploadLimits
{
MaxFileSizeMB = 64,
MaxAttachmentsPerMessage = 4
};
long maxImageBytes = limits.MaxImageSizeBytes;
long imageCeiling = limits.MaxForKind(AttachmentKind.Image);
long requestBody = limits.MaxRequestBodyBytes;
var limits = new UploadLimits();
long imageBytes = limits.MaxImageSizeBytes;
long imageCapForKind = limits.MaxForKind(AttachmentKind.Image);
```
## Notes
- Changing MaxAttachmentsPerMessage scales the MaxRequestBodyBytes non-linearly; the request-body cap will constrain multipart uploads even if per-file size increases.
- Defaults are tied to HubConstants; if those constants change, the default limits change too unless overridden in the Uploads configuration.
- The `MaxRequestBodyBytes` computation ties the per-attachment cap to the file-size ceiling, so increasing `MaxAttachmentsPerMessage` scales the maximum allowed request body accordingly.
- All byte-based properties are derived from their MB counterparts, so changes to the configuration flow through to enforcement automatically.
- If [`AttachmentKind`](../../EchoHub.Core/Models/AttachmentKind.cs.md) includes kinds beyond Image and Audio, those other kinds fall back to the general `MaxFileSizeBytes` in `MaxForKind`.