Files
Relay/RelayShared/Services/ChatMessageContent.cs
2026-06-06 23:38:50 -04:00

44 lines
2.3 KiB
C#

namespace RelayShared.Services;
/// <summary>
/// The plaintext payload of a chat message before E2E encryption is applied.
///
/// Lifecycle of a message:
/// 1. Client builds a ChatMessageContent (text + optional reply/attachment/mentions).
/// 2. Client JSON-serialises it, encrypts with the server's public key (RSA wrapping an
/// AES-GCM key), and sends the encrypted blob wrapped in a SocketEncryptedMessage.
/// 3. Server decrypts with its private key, re-encrypts with the channel DB key, stores it.
/// 4. For each recipient, server decrypts from DB key and re-encrypts with that recipient's
/// public key, then delivers via SocketEncryptedMessage.
/// 5. Recipient decrypts with their private key and JSON-deserialises back to ChatMessageContent.
///
/// This type is intentionally shared by RelayClient and RelayServer so both ends agree on the
/// JSON shape. Adding a field here lights up the whole pipeline automatically.
/// </summary>
public sealed class ChatMessageContent
{
/// <summary>The raw message body, including Markdown syntax and @mentions.</summary>
public string Text { get; set; } = string.Empty;
/// <summary>When set, this message is a reply. Carries the Surreal record id of the message being replied to.</summary>
public string? ReplyToId { get; set; }
/// <summary>Display name of the user being replied to. Lets the client render the quote bar without a lookup.</summary>
public string? ReplyToSenderUsername { get; set; }
/// <summary>Trimmed preview of the replied-to text (≤100 chars). Captured at send time so the server never has to look it up.</summary>
public string? ReplyPreview { get; set; }
/// <summary>Extracted usernames + special tokens ("everyone", "here"). Drives the ping-badge in the sidebar.</summary>
public List<string>? Mentions { get; set; }
/// <summary>Base64-encoded attachment bytes. Null when there's no attachment.</summary>
public string? AttachmentBase64 { get; set; }
/// <summary>MIME type of the attachment (e.g. "image/png"). Used to choose between BuildBase64ImageEmbed and BuildFileCard.</summary>
public string? AttachmentMimeType { get; set; }
/// <summary>Original filename as chosen by the sender. Shown as the file card label and used for the download path.</summary>
public string? AttachmentFileName { get; set; }
}