feat: Implement end-to-end encryption for channels

- Added EncryptionSalt and WrappedRoomKey properties to Channel model.
- Introduced RoomCrypto class for client-side encryption and decryption.
- Updated ChannelService to handle encrypted channels, including creation and rekeying.
- Modified ChannelsController to expose crypto metadata and rekey functionality.
- Enhanced IrcCommandHandler to block joining encrypted channels over IRC.
- Updated database schema with migration for new encryption fields.
- Refactored file validation and image processing services to accommodate encrypted channels.
- Added unit tests for RoomCrypto functionality and updated existing tests for channel services.
This commit is contained in:
HueByte
2026-07-16 03:50:23 +02:00
parent ea8e583ee5
commit e05b420ce9
36 changed files with 1400 additions and 67 deletions
+32 -3
View File
@@ -22,7 +22,8 @@ public record ChannelDto(
bool IsPublic,
int MessageCount,
DateTimeOffset CreatedAt,
bool IsProtected = false);
bool IsProtected = false,
bool IsEncrypted = false);
public record UserDto(
Guid Id,
@@ -34,13 +35,41 @@ public record UserDto(
public record SendMessageRequest(string ChannelName, string Content);
public record CreateChannelRequest(string Name, string? Topic = null, bool IsPublic = true, string? Password = null);
public record CreateChannelRequest(
string Name,
string? Topic = null,
bool IsPublic = true,
string? Password = null,
string? EncryptionSalt = null,
string? WrappedRoomKey = null);
/// <summary>
/// Public crypto metadata for a channel — enough for a client to derive its join
/// credential from a passphrase. Never includes the wrapped room key.
/// </summary>
public record ChannelCryptoDto(bool IsEncrypted, string? EncryptionSalt);
/// <summary>
/// Passphrase change for an encrypted channel: the client proves knowledge of the old
/// passphrase (old auth key), then supplies the re-wrapped room key under the new one.
/// </summary>
public record RekeyChannelRequest(
string OldPassword,
string NewPassword,
string NewEncryptionSalt,
string NewWrappedRoomKey);
public record UpdateTopicRequest(string? Topic);
public record SendUrlRequest(string Url);
public record JoinChannelResult(bool Success, List<MessageDto> History, string? Error = null, bool PasswordRequired = false);
public record JoinChannelResult(
bool Success,
List<MessageDto> History,
string? Error = null,
bool PasswordRequired = false,
string? EncryptionSalt = null,
string? WrappedRoomKey = null);
public record EmbedDto(
string? SiteName,