diff --git a/api/client-articles/index.html b/api/client-articles/index.html index 85d3cc3..06cd5de 100644 --- a/api/client-articles/index.html +++ b/api/client-articles/index.html @@ -11,7 +11,7 @@ - + diff --git a/api/client-articles/toc.json b/api/client-articles/toc.json index 6e9ffe5..e82f79a 100644 --- a/api/client-articles/toc.json +++ b/api/client-articles/toc.json @@ -1,2 +1,2 @@ -{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"}]} +{"order":100,"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"}]} diff --git a/api/client/EchoHub.Client.Services.ApiClient.html b/api/client/EchoHub.Client.Services.ApiClient.html index 4d809a9..565c4fe 100644 --- a/api/client/EchoHub.Client.Services.ApiClient.html +++ b/api/client/EchoHub.Client.Services.ApiClient.html @@ -532,6 +532,37 @@ Class ApiClient + +

+ GetEncryptionKeyAsync() + +

+ +
+
+ +
+
public Task<string> GetEncryptionKeyAsync()
+
+ + +

Returns

+
+
Task<string>
+
+
+ + + + + + + + + + +

diff --git a/api/client/EchoHub.Client.Services.ClientEncryptionService.html b/api/client/EchoHub.Client.Services.ClientEncryptionService.html new file mode 100644 index 0000000..f1d0d7e --- /dev/null +++ b/api/client/EchoHub.Client.Services.ClientEncryptionService.html @@ -0,0 +1,458 @@ + + + + + Class ClientEncryptionService | EchoHub Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
+
Table of Contents
+ +
+
+ +
+
+
+ +
+
+ + + +
+ +
+ + + +

+Class ClientEncryptionService +

+ +
+
Namespace
EchoHub.Client.Services
+
Assembly
EchoHub.Client.dll
+
+ +

Client-side encryption service. Uses the same AES-256-GCM format as the server +so messages are encrypted end-to-end between client and server.

+
+
+ +
+
public sealed class ClientEncryptionService : IMessageEncryptionService
+
+ + + + +
+
Inheritance
+
+ +
ClientEncryptionService
+
+
+ +
+
Implements
+
+ +
+
+ + +
+
Inherited Members
+
+ + + + + + +
+ + + + + + +

Constructors +

+ + + + +

+ ClientEncryptionService() + +

+ +
+
+ +
+
public ClientEncryptionService()
+
+ + + + + + + + + + + + + +

Properties +

+ + + + +

+ EncryptDatabaseEnabled + +

+ +

Whether database content should be encrypted at rest (server setting).

+
+
+ +
+
public bool EncryptDatabaseEnabled { get; }
+
+ + + + + +

Property Value

+
+
bool
+
+
+ + + + + + + + + + +

+ IsInitialized + +

+ +
+
+ +
+
public bool IsInitialized { get; }
+
+ + + + + +

Property Value

+
+
bool
+
+
+ + + + + + + + +

Methods +

+ + + + +

+ Decrypt(string) + +

+ +
+
+ +
+
public string Decrypt(string content)
+
+ +

Parameters

+
+
content string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ DecryptNullable(string?) + +

+ +
+
+ +
+
public string? DecryptNullable(string? value)
+
+ +

Parameters

+
+
value string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ Encrypt(string) + +

+ +
+
+ +
+
public string Encrypt(string plaintext)
+
+ +

Parameters

+
+
plaintext string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ EncryptNullable(string?) + +

+ +
+
+ +
+
public string? EncryptNullable(string? value)
+
+ +

Parameters

+
+
value string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ SetKey(string) + +

+ +

Initialize with the server's encryption key (fetched after login).

+
+
+ +
+
public void SetKey(string base64Key)
+
+ +

Parameters

+
+
base64Key string
+
+
+ + + + + + + + + + + + + +
+ + + + +
+ +
+ +
+
+ +
+ + + + diff --git a/api/client/EchoHub.Client.Services.EchoHubConnection.html b/api/client/EchoHub.Client.Services.EchoHubConnection.html index 5ebbae5..eb5a036 100644 --- a/api/client/EchoHub.Client.Services.EchoHubConnection.html +++ b/api/client/EchoHub.Client.Services.EchoHubConnection.html @@ -157,8 +157,8 @@ Class EchoHubConnection -

- EchoHubConnection(string, ApiClient) +

+ EchoHubConnection(string, ApiClient, ClientEncryptionService)

@@ -166,7 +166,7 @@ Class EchoHubConnection
-
public EchoHubConnection(string serverUrl, ApiClient apiClient)
+
public EchoHubConnection(string serverUrl, ApiClient apiClient, ClientEncryptionService encryption)

Parameters

@@ -175,6 +175,8 @@ Class EchoHubConnection
ApiClient
+
encryption ClientEncryptionService
+
diff --git a/api/client/EchoHub.Client.Services.html b/api/client/EchoHub.Client.Services.html index 69d707a..967c64d 100644 --- a/api/client/EchoHub.Client.Services.html +++ b/api/client/EchoHub.Client.Services.html @@ -98,6 +98,12 @@ Classes
ApiClient
+
+
ClientEncryptionService
+

Client-side encryption service. Uses the same AES-256-GCM format as the server +so messages are encrypted end-to-end between client and server.

+
+
EchoHubConnection
diff --git a/api/core-articles/index.html b/api/core-articles/index.html index 0dbd565..3303c4a 100644 --- a/api/core-articles/index.html +++ b/api/core-articles/index.html @@ -11,7 +11,7 @@ - + diff --git a/api/core-articles/toc.json b/api/core-articles/toc.json index 6e9ffe5..e82f79a 100644 --- a/api/core-articles/toc.json +++ b/api/core-articles/toc.json @@ -1,2 +1,2 @@ -{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"}]} +{"order":100,"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"}]} diff --git a/api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html b/api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html new file mode 100644 index 0000000..77e7216 --- /dev/null +++ b/api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html @@ -0,0 +1,328 @@ + + + + + Interface IMessageEncryptionService | EchoHub Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
+
Table of Contents
+ +
+
+ +
+
+
+ +
+
+ + + +
+ +
+ + + +

+Interface IMessageEncryptionService +

+ +
+
Namespace
EchoHub.Core.Contracts
+
Assembly
EchoHub.Core.dll
+
+ +
+
+ +
+
public interface IMessageEncryptionService
+
+ + + + + + + + + + + + + +

Properties +

+ + + + +

+ EncryptDatabaseEnabled + +

+ +

Whether database content should be encrypted at rest (server setting).

+
+
+ +
+
bool EncryptDatabaseEnabled { get; }
+
+ + + + + +

Property Value

+
+
bool
+
+
+ + + + + + + + +

Methods +

+ + + + +

+ Decrypt(string) + +

+ +
+
+ +
+
string Decrypt(string content)
+
+ +

Parameters

+
+
content string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ DecryptNullable(string?) + +

+ +
+
+ +
+
string? DecryptNullable(string? value)
+
+ +

Parameters

+
+
value string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ Encrypt(string) + +

+ +
+
+ +
+
string Encrypt(string plaintext)
+
+ +

Parameters

+
+
plaintext string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ EncryptNullable(string?) + +

+ +
+
+ +
+
string? EncryptNullable(string? value)
+
+ +

Parameters

+
+
value string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + +
+ + + + +
+ +
+ +
+
+ +
+ + + + diff --git a/api/core/EchoHub.Core.Contracts.html b/api/core/EchoHub.Core.Contracts.html index 055ca5b..65ffc73 100644 --- a/api/core/EchoHub.Core.Contracts.html +++ b/api/core/EchoHub.Core.Contracts.html @@ -114,6 +114,10 @@ Interfaces

Methods the server can invoke on connected clients.

+
+
IMessageEncryptionService
+
+
diff --git a/api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html b/api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html new file mode 100644 index 0000000..39a6c68 --- /dev/null +++ b/api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html @@ -0,0 +1,590 @@ + + + + + Class EncryptionKeyResponse | EchoHub Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
+
Table of Contents
+ +
+
+ +
+
+
+ +
+
+ + + +
+ +
+ + + +

+Class EncryptionKeyResponse +

+ +
+
Namespace
EchoHub.Core.DTOs
+
Assembly
EchoHub.Core.dll
+
+ +
+
+ +
+
public record EncryptionKeyResponse : IEquatable<EncryptionKeyResponse>
+
+ + + + +
+
Inheritance
+
+ +
EncryptionKeyResponse
+
+
+ +
+
Implements
+
+ +
+
+ + +
+
Inherited Members
+
+ + + + +
+ + + + + + +

Constructors +

+ + + + +

+ EncryptionKeyResponse(EncryptionKeyResponse) + +

+ +
+
+ +
+
protected EncryptionKeyResponse(EncryptionKeyResponse original)
+
+ +

Parameters

+
+
original EncryptionKeyResponse
+
+
+ + + + + + + + + + + + + + +

+ EncryptionKeyResponse(string) + +

+ +
+
+ +
+
public EncryptionKeyResponse(string Key)
+
+ +

Parameters

+
+
Key string
+
+
+ + + + + + + + + + + + +

Properties +

+ + + + +

+ EqualityContract + +

+ +
+
+ +
+
protected virtual Type EqualityContract { get; }
+
+ + + + + +

Property Value

+
+
Type
+
+
+ + + + + + + + + + +

+ Key + +

+ +
+
+ +
+
public string Key { get; init; }
+
+ + + + + +

Property Value

+
+
string
+
+
+ + + + + + + + +

Methods +

+ + + + +

+ Deconstruct(out string) + +

+ +
+
+ +
+
public void Deconstruct(out string Key)
+
+ +

Parameters

+
+
Key string
+
+
+ + + + + + + + + + + + + + +

+ Equals(EncryptionKeyResponse?) + +

+ +
+
+ +
+
public virtual bool Equals(EncryptionKeyResponse? other)
+
+ +

Parameters

+
+
other EncryptionKeyResponse
+
+
+ +

Returns

+
+
bool
+
+
+ + + + + + + + + + + + + +

+ Equals(object?) + +

+ +
+
+ +
+
public override bool Equals(object? obj)
+
+ +

Parameters

+
+
obj object
+
+
+ +

Returns

+
+
bool
+
+
+ + + + + + + + + + + + + +

+ GetHashCode() + +

+ +
+
+ +
+
public override int GetHashCode()
+
+ + +

Returns

+
+
int
+
+
+ + + + + + + + + + + + + +

+ PrintMembers(StringBuilder) + +

+ +
+
+ +
+
protected virtual bool PrintMembers(StringBuilder builder)
+
+ +

Parameters

+
+
builder StringBuilder
+
+
+ +

Returns

+
+
bool
+
+
+ + + + + + + + + + + + + +

+ ToString() + +

+ +
+
+ +
+
public override string ToString()
+
+ + +

Returns

+
+
string
+
+
+ + + + + + + + + + + +

Operators +

+ + + + +

+ operator ==(EncryptionKeyResponse?, EncryptionKeyResponse?) + +

+ +
+
+ +
+
public static bool operator ==(EncryptionKeyResponse? left, EncryptionKeyResponse? right)
+
+ +

Parameters

+
+
left EncryptionKeyResponse
+
+
right EncryptionKeyResponse
+
+
+ +

Returns

+
+
bool
+
+
+ + + + + + + + + + + + + +

+ operator !=(EncryptionKeyResponse?, EncryptionKeyResponse?) + +

+ +
+
+ +
+
public static bool operator !=(EncryptionKeyResponse? left, EncryptionKeyResponse? right)
+
+ +

Parameters

+
+
left EncryptionKeyResponse
+
+
right EncryptionKeyResponse
+
+
+ +

Returns

+
+
bool
+
+
+ + + + + + + + + + + + +
+ + + + +
+ +
+ +
+
+ +
+ + + + diff --git a/api/core/EchoHub.Core.DTOs.html b/api/core/EchoHub.Core.DTOs.html index 911af21..6e427d8 100644 --- a/api/core/EchoHub.Core.DTOs.html +++ b/api/core/EchoHub.Core.DTOs.html @@ -118,6 +118,10 @@ Classes
EmbedDto
+
+
EncryptionKeyResponse
+
+
ErrorResponse
diff --git a/api/server-articles/index.html b/api/server-articles/index.html index 013858c..5c4d08c 100644 --- a/api/server-articles/index.html +++ b/api/server-articles/index.html @@ -11,7 +11,7 @@ - + diff --git a/api/server-articles/toc.json b/api/server-articles/toc.json index 6e9ffe5..e82f79a 100644 --- a/api/server-articles/toc.json +++ b/api/server-articles/toc.json @@ -1,2 +1,2 @@ -{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"}]} +{"order":100,"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"}]} diff --git a/api/server-irc/EchoHub.Server.Irc.IrcBroadcaster.html b/api/server-irc/EchoHub.Server.Irc.IrcBroadcaster.html index 8b94bfd..49eaf3a 100644 --- a/api/server-irc/EchoHub.Server.Irc.IrcBroadcaster.html +++ b/api/server-irc/EchoHub.Server.Irc.IrcBroadcaster.html @@ -160,8 +160,8 @@ Class IrcBroadcaster -

- IrcBroadcaster(IrcGatewayService) +

+ IrcBroadcaster(IrcGatewayService, IMessageEncryptionService)

@@ -169,13 +169,15 @@ Class IrcBroadcaster
-
public IrcBroadcaster(IrcGatewayService gateway)
+
public IrcBroadcaster(IrcGatewayService gateway, IMessageEncryptionService encryption)

Parameters

gateway IrcGatewayService
+
encryption IMessageEncryptionService
+
diff --git a/api/server/EchoHub.Server.Controllers.ChannelsController.html b/api/server/EchoHub.Server.Controllers.ChannelsController.html index 112b2d8..6d6c4c7 100644 --- a/api/server/EchoHub.Server.Controllers.ChannelsController.html +++ b/api/server/EchoHub.Server.Controllers.ChannelsController.html @@ -159,8 +159,8 @@ public class ChannelsController : ControllerBase -

- ChannelsController(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService) +

+ ChannelsController(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService, IMessageEncryptionService)

@@ -168,7 +168,7 @@ public class ChannelsController : ControllerBase
-
public ChannelsController(EchoHubDbContext db, FileStorageService fileStorage, ImageToAsciiService asciiService, IHttpClientFactory httpClientFactory, IChatService chatService)
+
public ChannelsController(EchoHubDbContext db, FileStorageService fileStorage, ImageToAsciiService asciiService, IHttpClientFactory httpClientFactory, IChatService chatService, IMessageEncryptionService encryption)

Parameters

@@ -183,6 +183,8 @@ public class ChannelsController : ControllerBase
chatService IChatService
+
encryption IMessageEncryptionService
+
diff --git a/api/server/EchoHub.Server.Controllers.ServerController.html b/api/server/EchoHub.Server.Controllers.ServerController.html index 42d11a5..dad1c5c 100644 --- a/api/server/EchoHub.Server.Controllers.ServerController.html +++ b/api/server/EchoHub.Server.Controllers.ServerController.html @@ -192,6 +192,40 @@ public class ServerController : ControllerBase + + +

+ GetEncryptionKey() + +

+ +
+
+ +
+
[HttpGet("encryption-key")]
+[Authorize]
+[EnableRateLimiting("auth")]
+public IActionResult GetEncryptionKey()
+
+ + +

Returns

+
+
IActionResult
+
+
+ + + + + + + + + + +

diff --git a/api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html b/api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html new file mode 100644 index 0000000..a56b014 --- /dev/null +++ b/api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html @@ -0,0 +1,306 @@ + + + + + Class AddEncryptionSupport | EchoHub Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
+
Table of Contents
+ +
+
+ +
+
+
+ +
+
+ + + +
+ +
+ + + +

+Class AddEncryptionSupport +

+ +
+
Namespace
EchoHub.Server.Data.Migrations
+
Assembly
EchoHub.Server.dll
+
+ +
+
+ +
+
[DbContext(typeof(EchoHubDbContext))]
+[Migration("20260220133627_AddEncryptionSupport")]
+public class AddEncryptionSupport : Migration
+
+ + + + +
+
Inheritance
+
+ +
Migration
+
AddEncryptionSupport
+
+
+ + + +
+
Inherited Members
+
+ + + + + + + +
+ + + + + + +

Constructors +

+ + + + +

+ AddEncryptionSupport() + +

+ +
+
+ +
+
public AddEncryptionSupport()
+
+ + + + + + + + + + + + + +

Methods +

+ + + + +

+ BuildTargetModel(ModelBuilder) + +

+ +
+
+ +
+
protected override void BuildTargetModel(ModelBuilder modelBuilder)
+
+ +

Parameters

+
+
modelBuilder ModelBuilder
+
+
+ + + + + + + + + + + + + + +

+ Down(MigrationBuilder) + +

+ +
+
+ +
+
protected override void Down(MigrationBuilder migrationBuilder)
+
+ +

Parameters

+
+
migrationBuilder MigrationBuilder
+
+
+ + + + + + + + + + + + + + +

+ Up(MigrationBuilder) + +

+ +
+
+ +
+
protected override void Up(MigrationBuilder migrationBuilder)
+
+ +

Parameters

+
+
migrationBuilder MigrationBuilder
+
+
+ + + + + + + + + + + + + +
+ + + + +
+ +
+ +
+
+ +
+ + + + diff --git a/api/server/EchoHub.Server.Data.Migrations.html b/api/server/EchoHub.Server.Data.Migrations.html index 9f757d7..c8ec9de 100644 --- a/api/server/EchoHub.Server.Data.Migrations.html +++ b/api/server/EchoHub.Server.Data.Migrations.html @@ -102,6 +102,10 @@ Classes
AddChannelMembership
+
+
AddEncryptionSupport
+
+
AddMessageEmbed
diff --git a/api/server/EchoHub.Server.Services.ChatService.html b/api/server/EchoHub.Server.Services.ChatService.html index c9ad965..f6f0439 100644 --- a/api/server/EchoHub.Server.Services.ChatService.html +++ b/api/server/EchoHub.Server.Services.ChatService.html @@ -160,8 +160,8 @@ Class ChatService -

- ChatService(IServiceScopeFactory, PresenceTracker, IEnumerable<IChatBroadcaster>, LinkEmbedService, ILogger<ChatService>) +

+ ChatService(IServiceScopeFactory, PresenceTracker, IEnumerable<IChatBroadcaster>, LinkEmbedService, IMessageEncryptionService, ILogger<ChatService>)

@@ -169,7 +169,7 @@ Class ChatService
-
public ChatService(IServiceScopeFactory scopeFactory, PresenceTracker presenceTracker, IEnumerable<IChatBroadcaster> broadcasters, LinkEmbedService embedService, ILogger<ChatService> logger)
+
public ChatService(IServiceScopeFactory scopeFactory, PresenceTracker presenceTracker, IEnumerable<IChatBroadcaster> broadcasters, LinkEmbedService embedService, IMessageEncryptionService encryption, ILogger<ChatService> logger)

Parameters

@@ -182,6 +182,8 @@ Class ChatService
embedService LinkEmbedService
+
encryption IMessageEncryptionService
+
logger ILogger<ChatService>
diff --git a/api/server/EchoHub.Server.Services.MessageEncryptionService.html b/api/server/EchoHub.Server.Services.MessageEncryptionService.html new file mode 100644 index 0000000..1c89221 --- /dev/null +++ b/api/server/EchoHub.Server.Services.MessageEncryptionService.html @@ -0,0 +1,403 @@ + + + + + Class MessageEncryptionService | EchoHub Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
+
Table of Contents
+ +
+
+ +
+
+
+ +
+
+ + + +
+ +
+ + + +

+Class MessageEncryptionService +

+ +
+
Namespace
EchoHub.Server.Services
+
Assembly
EchoHub.Server.dll
+
+ +
+
+ +
+
public class MessageEncryptionService : IMessageEncryptionService
+
+ + + + +
+
Inheritance
+
+ +
MessageEncryptionService
+
+
+ +
+
Implements
+
+ +
+
+ + +
+
Inherited Members
+
+ + + + + + + +
+ + + + + + +

Constructors +

+ + + + +

+ MessageEncryptionService(IConfiguration, ILogger<MessageEncryptionService>) + +

+ +
+
+ +
+
public MessageEncryptionService(IConfiguration configuration, ILogger<MessageEncryptionService> logger)
+
+ +

Parameters

+
+
configuration IConfiguration
+
+
logger ILogger<MessageEncryptionService>
+
+
+ + + + + + + + + + + + +

Properties +

+ + + + +

+ EncryptDatabaseEnabled + +

+ +

Whether database content should be encrypted at rest (server setting).

+
+
+ +
+
public bool EncryptDatabaseEnabled { get; }
+
+ + + + + +

Property Value

+
+
bool
+
+
+ + + + + + + + +

Methods +

+ + + + +

+ Decrypt(string) + +

+ +
+
+ +
+
public string Decrypt(string content)
+
+ +

Parameters

+
+
content string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ DecryptNullable(string?) + +

+ +
+
+ +
+
public string? DecryptNullable(string? value)
+
+ +

Parameters

+
+
value string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ Encrypt(string) + +

+ +
+
+ +
+
public string Encrypt(string plaintext)
+
+ +

Parameters

+
+
plaintext string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + + +

+ EncryptNullable(string?) + +

+ +
+
+ +
+
public string? EncryptNullable(string? value)
+
+ +

Parameters

+
+
value string
+
+
+ +

Returns

+
+
string
+
+
+ + + + + + + + + + + + +
+ + + + +
+ +
+ +
+
+ +
+ + + + diff --git a/api/server/EchoHub.Server.Services.html b/api/server/EchoHub.Server.Services.html index 4829c60..54d4e34 100644 --- a/api/server/EchoHub.Server.Services.html +++ b/api/server/EchoHub.Server.Services.html @@ -114,6 +114,10 @@ Classes
LinkEmbedService
+
+
MessageEncryptionService
+
+
PresenceTracker
diff --git a/api/toc.html b/api/toc.html index d5f30da..74a8304 100644 --- a/api/toc.html +++ b/api/toc.html @@ -78,6 +78,9 @@
  • ApiClient
  • +
  • + ClientEncryptionService +
  • EchoHubConnection
  • @@ -172,7 +175,14 @@
  • - Articles + + Articles + +
  • @@ -216,6 +226,9 @@
  • IEchoHubClient
  • +
  • + IMessageEncryptionService +
  • @@ -241,6 +254,9 @@
  • EmbedDto
  • +
  • + EncryptionKeyResponse +
  • ErrorResponse
  • @@ -331,7 +347,14 @@
  • - Articles + + Articles + +
  • @@ -401,6 +424,9 @@
  • AddChannelMembership
  • +
  • + AddEncryptionSupport +
  • AddMessageEmbed
  • @@ -442,6 +468,9 @@
  • LinkEmbedService
  • +
  • + MessageEncryptionService +
  • PresenceTracker
  • @@ -472,7 +501,14 @@
  • - Articles + + Articles + +
  • diff --git a/api/toc.json b/api/toc.json index a15824a..6e526ac 100644 --- a/api/toc.json +++ b/api/toc.json @@ -1,2 +1,2 @@ -{"items":[{"name":"Client","items":[{"name":"API Reference","includedFrom":"~/_api_meta/client/toc.yml","items":[{"name":"EchoHub.Client","href":"client/EchoHub.Client.html","topicHref":"client/EchoHub.Client.html","topicUid":"EchoHub.Client","type":"Namespace","items":[{"name":"AppOrchestrator","href":"client/EchoHub.Client.AppOrchestrator.html","topicHref":"client/EchoHub.Client.AppOrchestrator.html","topicUid":"EchoHub.Client.AppOrchestrator","type":"Class"},{"name":"AsyncRunner","href":"client/EchoHub.Client.AsyncRunner.html","topicHref":"client/EchoHub.Client.AsyncRunner.html","topicUid":"EchoHub.Client.AsyncRunner","type":"Class"}]},{"name":"EchoHub.Client.Commands","href":"client/EchoHub.Client.Commands.html","topicHref":"client/EchoHub.Client.Commands.html","topicUid":"EchoHub.Client.Commands","type":"Namespace","items":[{"name":"CommandHandler","href":"client/EchoHub.Client.Commands.CommandHandler.html","topicHref":"client/EchoHub.Client.Commands.CommandHandler.html","topicUid":"EchoHub.Client.Commands.CommandHandler","type":"Class"},{"name":"CommandResult","href":"client/EchoHub.Client.Commands.CommandResult.html","topicHref":"client/EchoHub.Client.Commands.CommandResult.html","topicUid":"EchoHub.Client.Commands.CommandResult","type":"Class"}]},{"name":"EchoHub.Client.Config","href":"client/EchoHub.Client.Config.html","topicHref":"client/EchoHub.Client.Config.html","topicUid":"EchoHub.Client.Config","type":"Namespace","items":[{"name":"AccountPreset","href":"client/EchoHub.Client.Config.AccountPreset.html","topicHref":"client/EchoHub.Client.Config.AccountPreset.html","topicUid":"EchoHub.Client.Config.AccountPreset","type":"Class"},{"name":"ClientConfig","href":"client/EchoHub.Client.Config.ClientConfig.html","topicHref":"client/EchoHub.Client.Config.ClientConfig.html","topicUid":"EchoHub.Client.Config.ClientConfig","type":"Class"},{"name":"ConfigManager","href":"client/EchoHub.Client.Config.ConfigManager.html","topicHref":"client/EchoHub.Client.Config.ConfigManager.html","topicUid":"EchoHub.Client.Config.ConfigManager","type":"Class"},{"name":"NotificationConfig","href":"client/EchoHub.Client.Config.NotificationConfig.html","topicHref":"client/EchoHub.Client.Config.NotificationConfig.html","topicUid":"EchoHub.Client.Config.NotificationConfig","type":"Class"},{"name":"SavedServer","href":"client/EchoHub.Client.Config.SavedServer.html","topicHref":"client/EchoHub.Client.Config.SavedServer.html","topicUid":"EchoHub.Client.Config.SavedServer","type":"Class"}]},{"name":"EchoHub.Client.Services","href":"client/EchoHub.Client.Services.html","topicHref":"client/EchoHub.Client.Services.html","topicUid":"EchoHub.Client.Services","type":"Namespace","items":[{"name":"ApiClient","href":"client/EchoHub.Client.Services.ApiClient.html","topicHref":"client/EchoHub.Client.Services.ApiClient.html","topicUid":"EchoHub.Client.Services.ApiClient","type":"Class"},{"name":"EchoHubConnection","href":"client/EchoHub.Client.Services.EchoHubConnection.html","topicHref":"client/EchoHub.Client.Services.EchoHubConnection.html","topicUid":"EchoHub.Client.Services.EchoHubConnection","type":"Class"},{"name":"NotificationSoundService","href":"client/EchoHub.Client.Services.NotificationSoundService.html","topicHref":"client/EchoHub.Client.Services.NotificationSoundService.html","topicUid":"EchoHub.Client.Services.NotificationSoundService","type":"Class"},{"name":"UpdateChecker","href":"client/EchoHub.Client.Services.UpdateChecker.html","topicHref":"client/EchoHub.Client.Services.UpdateChecker.html","topicUid":"EchoHub.Client.Services.UpdateChecker","type":"Class"}]},{"name":"EchoHub.Client.Themes","href":"client/EchoHub.Client.Themes.html","topicHref":"client/EchoHub.Client.Themes.html","topicUid":"EchoHub.Client.Themes","type":"Namespace","items":[{"name":"Theme","href":"client/EchoHub.Client.Themes.Theme.html","topicHref":"client/EchoHub.Client.Themes.Theme.html","topicUid":"EchoHub.Client.Themes.Theme","type":"Class"},{"name":"ThemeColors","href":"client/EchoHub.Client.Themes.ThemeColors.html","topicHref":"client/EchoHub.Client.Themes.ThemeColors.html","topicUid":"EchoHub.Client.Themes.ThemeColors","type":"Class"},{"name":"ThemeManager","href":"client/EchoHub.Client.Themes.ThemeManager.html","topicHref":"client/EchoHub.Client.Themes.ThemeManager.html","topicUid":"EchoHub.Client.Themes.ThemeManager","type":"Class"}]},{"name":"EchoHub.Client.UI","href":"client/EchoHub.Client.UI.html","topicHref":"client/EchoHub.Client.UI.html","topicUid":"EchoHub.Client.UI","type":"Namespace","items":[{"name":"ChannelListSource","href":"client/EchoHub.Client.UI.ChannelListSource.html","topicHref":"client/EchoHub.Client.UI.ChannelListSource.html","topicUid":"EchoHub.Client.UI.ChannelListSource","type":"Class"},{"name":"ChatColors","href":"client/EchoHub.Client.UI.ChatColors.html","topicHref":"client/EchoHub.Client.UI.ChatColors.html","topicUid":"EchoHub.Client.UI.ChatColors","type":"Class"},{"name":"ChatLine","href":"client/EchoHub.Client.UI.ChatLine.html","topicHref":"client/EchoHub.Client.UI.ChatLine.html","topicUid":"EchoHub.Client.UI.ChatLine","type":"Class"},{"name":"ChatListSource","href":"client/EchoHub.Client.UI.ChatListSource.html","topicHref":"client/EchoHub.Client.UI.ChatListSource.html","topicUid":"EchoHub.Client.UI.ChatListSource","type":"Class"},{"name":"ChatSegment","href":"client/EchoHub.Client.UI.ChatSegment.html","topicHref":"client/EchoHub.Client.UI.ChatSegment.html","topicUid":"EchoHub.Client.UI.ChatSegment","type":"Class"},{"name":"ColorHelper","href":"client/EchoHub.Client.UI.ColorHelper.html","topicHref":"client/EchoHub.Client.UI.ColorHelper.html","topicUid":"EchoHub.Client.UI.ColorHelper","type":"Class"},{"name":"ConnectDialog","href":"client/EchoHub.Client.UI.ConnectDialog.html","topicHref":"client/EchoHub.Client.UI.ConnectDialog.html","topicUid":"EchoHub.Client.UI.ConnectDialog","type":"Class"},{"name":"ConnectDialogResult","href":"client/EchoHub.Client.UI.ConnectDialogResult.html","topicHref":"client/EchoHub.Client.UI.ConnectDialogResult.html","topicUid":"EchoHub.Client.UI.ConnectDialogResult","type":"Class"},{"name":"CreateChannelDialog","href":"client/EchoHub.Client.UI.CreateChannelDialog.html","topicHref":"client/EchoHub.Client.UI.CreateChannelDialog.html","topicUid":"EchoHub.Client.UI.CreateChannelDialog","type":"Class"},{"name":"CreateChannelResult","href":"client/EchoHub.Client.UI.CreateChannelResult.html","topicHref":"client/EchoHub.Client.UI.CreateChannelResult.html","topicUid":"EchoHub.Client.UI.CreateChannelResult","type":"Class"},{"name":"EmojiHelper","href":"client/EchoHub.Client.UI.EmojiHelper.html","topicHref":"client/EchoHub.Client.UI.EmojiHelper.html","topicUid":"EchoHub.Client.UI.EmojiHelper","type":"Class"},{"name":"MainWindow","href":"client/EchoHub.Client.UI.MainWindow.html","topicHref":"client/EchoHub.Client.UI.MainWindow.html","topicUid":"EchoHub.Client.UI.MainWindow","type":"Class"},{"name":"ProfileAction","href":"client/EchoHub.Client.UI.ProfileAction.html","topicHref":"client/EchoHub.Client.UI.ProfileAction.html","topicUid":"EchoHub.Client.UI.ProfileAction","type":"Enum"},{"name":"ProfileEditDialog","href":"client/EchoHub.Client.UI.ProfileEditDialog.html","topicHref":"client/EchoHub.Client.UI.ProfileEditDialog.html","topicUid":"EchoHub.Client.UI.ProfileEditDialog","type":"Class"},{"name":"ProfileEditResult","href":"client/EchoHub.Client.UI.ProfileEditResult.html","topicHref":"client/EchoHub.Client.UI.ProfileEditResult.html","topicUid":"EchoHub.Client.UI.ProfileEditResult","type":"Class"},{"name":"ProfileViewDialog","href":"client/EchoHub.Client.UI.ProfileViewDialog.html","topicHref":"client/EchoHub.Client.UI.ProfileViewDialog.html","topicUid":"EchoHub.Client.UI.ProfileViewDialog","type":"Class"},{"name":"StatusDialog","href":"client/EchoHub.Client.UI.StatusDialog.html","topicHref":"client/EchoHub.Client.UI.StatusDialog.html","topicUid":"EchoHub.Client.UI.StatusDialog","type":"Class"},{"name":"StatusDialogResult","href":"client/EchoHub.Client.UI.StatusDialogResult.html","topicHref":"client/EchoHub.Client.UI.StatusDialogResult.html","topicUid":"EchoHub.Client.UI.StatusDialogResult","type":"Class"},{"name":"UserListSource","href":"client/EchoHub.Client.UI.UserListSource.html","topicHref":"client/EchoHub.Client.UI.UserListSource.html","topicUid":"EchoHub.Client.UI.UserListSource","type":"Class"}]}]},{"name":"Articles","href":"client-articles/index.html","tocHref":"client-articles/toc.html","topicHref":"client-articles/index.html"}]},{"name":"Core","items":[{"name":"API Reference","includedFrom":"~/_api_meta/core/toc.yml","items":[{"name":"EchoHub.Core.Constants","href":"core/EchoHub.Core.Constants.html","topicHref":"core/EchoHub.Core.Constants.html","topicUid":"EchoHub.Core.Constants","type":"Namespace","items":[{"name":"HubConstants","href":"core/EchoHub.Core.Constants.HubConstants.html","topicHref":"core/EchoHub.Core.Constants.HubConstants.html","topicUid":"EchoHub.Core.Constants.HubConstants","type":"Class"},{"name":"ValidationConstants","href":"core/EchoHub.Core.Constants.ValidationConstants.html","topicHref":"core/EchoHub.Core.Constants.ValidationConstants.html","topicUid":"EchoHub.Core.Constants.ValidationConstants","type":"Class"}]},{"name":"EchoHub.Core.Contracts","href":"core/EchoHub.Core.Contracts.html","topicHref":"core/EchoHub.Core.Contracts.html","topicUid":"EchoHub.Core.Contracts","type":"Namespace","items":[{"name":"ChannelListItem","href":"core/EchoHub.Core.Contracts.ChannelListItem.html","topicHref":"core/EchoHub.Core.Contracts.ChannelListItem.html","topicUid":"EchoHub.Core.Contracts.ChannelListItem","type":"Class"},{"name":"IChatBroadcaster","href":"core/EchoHub.Core.Contracts.IChatBroadcaster.html","topicHref":"core/EchoHub.Core.Contracts.IChatBroadcaster.html","topicUid":"EchoHub.Core.Contracts.IChatBroadcaster","type":"Interface"},{"name":"IChatService","href":"core/EchoHub.Core.Contracts.IChatService.html","topicHref":"core/EchoHub.Core.Contracts.IChatService.html","topicUid":"EchoHub.Core.Contracts.IChatService","type":"Interface"},{"name":"IEchoHubClient","href":"core/EchoHub.Core.Contracts.IEchoHubClient.html","topicHref":"core/EchoHub.Core.Contracts.IEchoHubClient.html","topicUid":"EchoHub.Core.Contracts.IEchoHubClient","type":"Interface"}]},{"name":"EchoHub.Core.DTOs","href":"core/EchoHub.Core.DTOs.html","topicHref":"core/EchoHub.Core.DTOs.html","topicUid":"EchoHub.Core.DTOs","type":"Namespace","items":[{"name":"AssignRoleRequest","href":"core/EchoHub.Core.DTOs.AssignRoleRequest.html","topicHref":"core/EchoHub.Core.DTOs.AssignRoleRequest.html","topicUid":"EchoHub.Core.DTOs.AssignRoleRequest","type":"Class"},{"name":"AvatarUploadResponse","href":"core/EchoHub.Core.DTOs.AvatarUploadResponse.html","topicHref":"core/EchoHub.Core.DTOs.AvatarUploadResponse.html","topicUid":"EchoHub.Core.DTOs.AvatarUploadResponse","type":"Class"},{"name":"BanRequest","href":"core/EchoHub.Core.DTOs.BanRequest.html","topicHref":"core/EchoHub.Core.DTOs.BanRequest.html","topicUid":"EchoHub.Core.DTOs.BanRequest","type":"Class"},{"name":"ChannelDto","href":"core/EchoHub.Core.DTOs.ChannelDto.html","topicHref":"core/EchoHub.Core.DTOs.ChannelDto.html","topicUid":"EchoHub.Core.DTOs.ChannelDto","type":"Class"},{"name":"CreateChannelRequest","href":"core/EchoHub.Core.DTOs.CreateChannelRequest.html","topicHref":"core/EchoHub.Core.DTOs.CreateChannelRequest.html","topicUid":"EchoHub.Core.DTOs.CreateChannelRequest","type":"Class"},{"name":"EmbedDto","href":"core/EchoHub.Core.DTOs.EmbedDto.html","topicHref":"core/EchoHub.Core.DTOs.EmbedDto.html","topicUid":"EchoHub.Core.DTOs.EmbedDto","type":"Class"},{"name":"ErrorResponse","href":"core/EchoHub.Core.DTOs.ErrorResponse.html","topicHref":"core/EchoHub.Core.DTOs.ErrorResponse.html","topicUid":"EchoHub.Core.DTOs.ErrorResponse","type":"Class"},{"name":"KickRequest","href":"core/EchoHub.Core.DTOs.KickRequest.html","topicHref":"core/EchoHub.Core.DTOs.KickRequest.html","topicUid":"EchoHub.Core.DTOs.KickRequest","type":"Class"},{"name":"LoginRequest","href":"core/EchoHub.Core.DTOs.LoginRequest.html","topicHref":"core/EchoHub.Core.DTOs.LoginRequest.html","topicUid":"EchoHub.Core.DTOs.LoginRequest","type":"Class"},{"name":"LoginResponse","href":"core/EchoHub.Core.DTOs.LoginResponse.html","topicHref":"core/EchoHub.Core.DTOs.LoginResponse.html","topicUid":"EchoHub.Core.DTOs.LoginResponse","type":"Class"},{"name":"MessageDto","href":"core/EchoHub.Core.DTOs.MessageDto.html","topicHref":"core/EchoHub.Core.DTOs.MessageDto.html","topicUid":"EchoHub.Core.DTOs.MessageDto","type":"Class"},{"name":"MuteRequest","href":"core/EchoHub.Core.DTOs.MuteRequest.html","topicHref":"core/EchoHub.Core.DTOs.MuteRequest.html","topicUid":"EchoHub.Core.DTOs.MuteRequest","type":"Class"},{"name":"PaginatedResponse","href":"core/EchoHub.Core.DTOs.PaginatedResponse-1.html","topicHref":"core/EchoHub.Core.DTOs.PaginatedResponse-1.html","topicUid":"EchoHub.Core.DTOs.PaginatedResponse`1","type":"Class"},{"name":"RefreshRequest","href":"core/EchoHub.Core.DTOs.RefreshRequest.html","topicHref":"core/EchoHub.Core.DTOs.RefreshRequest.html","topicUid":"EchoHub.Core.DTOs.RefreshRequest","type":"Class"},{"name":"RegisterRequest","href":"core/EchoHub.Core.DTOs.RegisterRequest.html","topicHref":"core/EchoHub.Core.DTOs.RegisterRequest.html","topicUid":"EchoHub.Core.DTOs.RegisterRequest","type":"Class"},{"name":"SendMessageRequest","href":"core/EchoHub.Core.DTOs.SendMessageRequest.html","topicHref":"core/EchoHub.Core.DTOs.SendMessageRequest.html","topicUid":"EchoHub.Core.DTOs.SendMessageRequest","type":"Class"},{"name":"SendUrlRequest","href":"core/EchoHub.Core.DTOs.SendUrlRequest.html","topicHref":"core/EchoHub.Core.DTOs.SendUrlRequest.html","topicUid":"EchoHub.Core.DTOs.SendUrlRequest","type":"Class"},{"name":"ServerStatusDto","href":"core/EchoHub.Core.DTOs.ServerStatusDto.html","topicHref":"core/EchoHub.Core.DTOs.ServerStatusDto.html","topicUid":"EchoHub.Core.DTOs.ServerStatusDto","type":"Class"},{"name":"UpdateProfileRequest","href":"core/EchoHub.Core.DTOs.UpdateProfileRequest.html","topicHref":"core/EchoHub.Core.DTOs.UpdateProfileRequest.html","topicUid":"EchoHub.Core.DTOs.UpdateProfileRequest","type":"Class"},{"name":"UpdateStatusRequest","href":"core/EchoHub.Core.DTOs.UpdateStatusRequest.html","topicHref":"core/EchoHub.Core.DTOs.UpdateStatusRequest.html","topicUid":"EchoHub.Core.DTOs.UpdateStatusRequest","type":"Class"},{"name":"UpdateTopicRequest","href":"core/EchoHub.Core.DTOs.UpdateTopicRequest.html","topicHref":"core/EchoHub.Core.DTOs.UpdateTopicRequest.html","topicUid":"EchoHub.Core.DTOs.UpdateTopicRequest","type":"Class"},{"name":"UserDto","href":"core/EchoHub.Core.DTOs.UserDto.html","topicHref":"core/EchoHub.Core.DTOs.UserDto.html","topicUid":"EchoHub.Core.DTOs.UserDto","type":"Class"},{"name":"UserPresenceDto","href":"core/EchoHub.Core.DTOs.UserPresenceDto.html","topicHref":"core/EchoHub.Core.DTOs.UserPresenceDto.html","topicUid":"EchoHub.Core.DTOs.UserPresenceDto","type":"Class"},{"name":"UserProfileDto","href":"core/EchoHub.Core.DTOs.UserProfileDto.html","topicHref":"core/EchoHub.Core.DTOs.UserProfileDto.html","topicUid":"EchoHub.Core.DTOs.UserProfileDto","type":"Class"}]},{"name":"EchoHub.Core.Models","href":"core/EchoHub.Core.Models.html","topicHref":"core/EchoHub.Core.Models.html","topicUid":"EchoHub.Core.Models","type":"Namespace","items":[{"name":"Channel","href":"core/EchoHub.Core.Models.Channel.html","topicHref":"core/EchoHub.Core.Models.Channel.html","topicUid":"EchoHub.Core.Models.Channel","type":"Class"},{"name":"ChannelMembership","href":"core/EchoHub.Core.Models.ChannelMembership.html","topicHref":"core/EchoHub.Core.Models.ChannelMembership.html","topicUid":"EchoHub.Core.Models.ChannelMembership","type":"Class"},{"name":"Message","href":"core/EchoHub.Core.Models.Message.html","topicHref":"core/EchoHub.Core.Models.Message.html","topicUid":"EchoHub.Core.Models.Message","type":"Class"},{"name":"MessageType","href":"core/EchoHub.Core.Models.MessageType.html","topicHref":"core/EchoHub.Core.Models.MessageType.html","topicUid":"EchoHub.Core.Models.MessageType","type":"Enum"},{"name":"RefreshToken","href":"core/EchoHub.Core.Models.RefreshToken.html","topicHref":"core/EchoHub.Core.Models.RefreshToken.html","topicUid":"EchoHub.Core.Models.RefreshToken","type":"Class"},{"name":"ServerRole","href":"core/EchoHub.Core.Models.ServerRole.html","topicHref":"core/EchoHub.Core.Models.ServerRole.html","topicUid":"EchoHub.Core.Models.ServerRole","type":"Enum"},{"name":"User","href":"core/EchoHub.Core.Models.User.html","topicHref":"core/EchoHub.Core.Models.User.html","topicUid":"EchoHub.Core.Models.User","type":"Class"},{"name":"UserStatus","href":"core/EchoHub.Core.Models.UserStatus.html","topicHref":"core/EchoHub.Core.Models.UserStatus.html","topicUid":"EchoHub.Core.Models.UserStatus","type":"Enum"}]}]},{"name":"Articles","href":"core-articles/index.html","tocHref":"core-articles/toc.html","topicHref":"core-articles/index.html"}]},{"name":"Server","items":[{"name":"API Reference","includedFrom":"~/_api_meta/server/toc.yml","items":[{"name":"EchoHub.Server.Auth","href":"server/EchoHub.Server.Auth.html","topicHref":"server/EchoHub.Server.Auth.html","topicUid":"EchoHub.Server.Auth","type":"Namespace","items":[{"name":"JwtTokenService","href":"server/EchoHub.Server.Auth.JwtTokenService.html","topicHref":"server/EchoHub.Server.Auth.JwtTokenService.html","topicUid":"EchoHub.Server.Auth.JwtTokenService","type":"Class"}]},{"name":"EchoHub.Server.Controllers","href":"server/EchoHub.Server.Controllers.html","topicHref":"server/EchoHub.Server.Controllers.html","topicUid":"EchoHub.Server.Controllers","type":"Namespace","items":[{"name":"AuthController","href":"server/EchoHub.Server.Controllers.AuthController.html","topicHref":"server/EchoHub.Server.Controllers.AuthController.html","topicUid":"EchoHub.Server.Controllers.AuthController","type":"Class"},{"name":"ChannelsController","href":"server/EchoHub.Server.Controllers.ChannelsController.html","topicHref":"server/EchoHub.Server.Controllers.ChannelsController.html","topicUid":"EchoHub.Server.Controllers.ChannelsController","type":"Class"},{"name":"FilesController","href":"server/EchoHub.Server.Controllers.FilesController.html","topicHref":"server/EchoHub.Server.Controllers.FilesController.html","topicUid":"EchoHub.Server.Controllers.FilesController","type":"Class"},{"name":"ModerationController","href":"server/EchoHub.Server.Controllers.ModerationController.html","topicHref":"server/EchoHub.Server.Controllers.ModerationController.html","topicUid":"EchoHub.Server.Controllers.ModerationController","type":"Class"},{"name":"ServerController","href":"server/EchoHub.Server.Controllers.ServerController.html","topicHref":"server/EchoHub.Server.Controllers.ServerController.html","topicUid":"EchoHub.Server.Controllers.ServerController","type":"Class"},{"name":"UsersController","href":"server/EchoHub.Server.Controllers.UsersController.html","topicHref":"server/EchoHub.Server.Controllers.UsersController.html","topicUid":"EchoHub.Server.Controllers.UsersController","type":"Class"}]},{"name":"EchoHub.Server.Data","href":"server/EchoHub.Server.Data.html","topicHref":"server/EchoHub.Server.Data.html","topicUid":"EchoHub.Server.Data","type":"Namespace","items":[{"name":"EchoHubDbContext","href":"server/EchoHub.Server.Data.EchoHubDbContext.html","topicHref":"server/EchoHub.Server.Data.EchoHubDbContext.html","topicUid":"EchoHub.Server.Data.EchoHubDbContext","type":"Class"}]},{"name":"EchoHub.Server.Data.Migrations","href":"server/EchoHub.Server.Data.Migrations.html","topicHref":"server/EchoHub.Server.Data.Migrations.html","topicUid":"EchoHub.Server.Data.Migrations","type":"Namespace","items":[{"name":"AddChannelIsPublic","href":"server/EchoHub.Server.Data.Migrations.AddChannelIsPublic.html","topicHref":"server/EchoHub.Server.Data.Migrations.AddChannelIsPublic.html","topicUid":"EchoHub.Server.Data.Migrations.AddChannelIsPublic","type":"Class"},{"name":"AddChannelMembership","href":"server/EchoHub.Server.Data.Migrations.AddChannelMembership.html","topicHref":"server/EchoHub.Server.Data.Migrations.AddChannelMembership.html","topicUid":"EchoHub.Server.Data.Migrations.AddChannelMembership","type":"Class"},{"name":"AddMessageEmbed","href":"server/EchoHub.Server.Data.Migrations.AddMessageEmbed.html","topicHref":"server/EchoHub.Server.Data.Migrations.AddMessageEmbed.html","topicUid":"EchoHub.Server.Data.Migrations.AddMessageEmbed","type":"Class"},{"name":"AddModerationRoles","href":"server/EchoHub.Server.Data.Migrations.AddModerationRoles.html","topicHref":"server/EchoHub.Server.Data.Migrations.AddModerationRoles.html","topicUid":"EchoHub.Server.Data.Migrations.AddModerationRoles","type":"Class"},{"name":"InitialCreate","href":"server/EchoHub.Server.Data.Migrations.InitialCreate.html","topicHref":"server/EchoHub.Server.Data.Migrations.InitialCreate.html","topicUid":"EchoHub.Server.Data.Migrations.InitialCreate","type":"Class"}]},{"name":"EchoHub.Server.Hubs","href":"server/EchoHub.Server.Hubs.html","topicHref":"server/EchoHub.Server.Hubs.html","topicUid":"EchoHub.Server.Hubs","type":"Namespace","items":[{"name":"ChatHub","href":"server/EchoHub.Server.Hubs.ChatHub.html","topicHref":"server/EchoHub.Server.Hubs.ChatHub.html","topicUid":"EchoHub.Server.Hubs.ChatHub","type":"Class"}]},{"name":"EchoHub.Server.Services","href":"server/EchoHub.Server.Services.html","topicHref":"server/EchoHub.Server.Services.html","topicUid":"EchoHub.Server.Services","type":"Namespace","items":[{"name":"ChatService","href":"server/EchoHub.Server.Services.ChatService.html","topicHref":"server/EchoHub.Server.Services.ChatService.html","topicUid":"EchoHub.Server.Services.ChatService","type":"Class"},{"name":"FileStorageService","href":"server/EchoHub.Server.Services.FileStorageService.html","topicHref":"server/EchoHub.Server.Services.FileStorageService.html","topicUid":"EchoHub.Server.Services.FileStorageService","type":"Class"},{"name":"FileValidationHelper","href":"server/EchoHub.Server.Services.FileValidationHelper.html","topicHref":"server/EchoHub.Server.Services.FileValidationHelper.html","topicUid":"EchoHub.Server.Services.FileValidationHelper","type":"Class"},{"name":"ImageToAsciiService","href":"server/EchoHub.Server.Services.ImageToAsciiService.html","topicHref":"server/EchoHub.Server.Services.ImageToAsciiService.html","topicUid":"EchoHub.Server.Services.ImageToAsciiService","type":"Class"},{"name":"LinkEmbedService","href":"server/EchoHub.Server.Services.LinkEmbedService.html","topicHref":"server/EchoHub.Server.Services.LinkEmbedService.html","topicUid":"EchoHub.Server.Services.LinkEmbedService","type":"Class"},{"name":"PresenceTracker","href":"server/EchoHub.Server.Services.PresenceTracker.html","topicHref":"server/EchoHub.Server.Services.PresenceTracker.html","topicUid":"EchoHub.Server.Services.PresenceTracker","type":"Class"},{"name":"ServerDirectoryService","href":"server/EchoHub.Server.Services.ServerDirectoryService.html","topicHref":"server/EchoHub.Server.Services.ServerDirectoryService.html","topicUid":"EchoHub.Server.Services.ServerDirectoryService","type":"Class"},{"name":"SignalRBroadcaster","href":"server/EchoHub.Server.Services.SignalRBroadcaster.html","topicHref":"server/EchoHub.Server.Services.SignalRBroadcaster.html","topicUid":"EchoHub.Server.Services.SignalRBroadcaster","type":"Class"}]},{"name":"EchoHub.Server.Setup","href":"server/EchoHub.Server.Setup.html","topicHref":"server/EchoHub.Server.Setup.html","topicUid":"EchoHub.Server.Setup","type":"Namespace","items":[{"name":"DataMigrationService","href":"server/EchoHub.Server.Setup.DataMigrationService.html","topicHref":"server/EchoHub.Server.Setup.DataMigrationService.html","topicUid":"EchoHub.Server.Setup.DataMigrationService","type":"Class"},{"name":"DatabaseSetup","href":"server/EchoHub.Server.Setup.DatabaseSetup.html","topicHref":"server/EchoHub.Server.Setup.DatabaseSetup.html","topicUid":"EchoHub.Server.Setup.DatabaseSetup","type":"Class"},{"name":"FirstRunSetup","href":"server/EchoHub.Server.Setup.FirstRunSetup.html","topicHref":"server/EchoHub.Server.Setup.FirstRunSetup.html","topicUid":"EchoHub.Server.Setup.FirstRunSetup","type":"Class"}]}]},{"name":"Articles","href":"server-articles/index.html","tocHref":"server-articles/toc.html","topicHref":"server-articles/index.html"}]},{"name":"Server.Irc","items":[{"name":"API Reference","includedFrom":"~/_api_meta/server-irc/toc.yml","items":[{"name":"EchoHub.Server.Irc","href":"server-irc/EchoHub.Server.Irc.html","topicHref":"server-irc/EchoHub.Server.Irc.html","topicUid":"EchoHub.Server.Irc","type":"Namespace","items":[{"name":"IrcBroadcaster","href":"server-irc/EchoHub.Server.Irc.IrcBroadcaster.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcBroadcaster.html","topicUid":"EchoHub.Server.Irc.IrcBroadcaster","type":"Class"},{"name":"IrcClientConnection","href":"server-irc/EchoHub.Server.Irc.IrcClientConnection.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcClientConnection.html","topicUid":"EchoHub.Server.Irc.IrcClientConnection","type":"Class"},{"name":"IrcCommandHandler","href":"server-irc/EchoHub.Server.Irc.IrcCommandHandler.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcCommandHandler.html","topicUid":"EchoHub.Server.Irc.IrcCommandHandler","type":"Class"},{"name":"IrcGatewayService","href":"server-irc/EchoHub.Server.Irc.IrcGatewayService.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcGatewayService.html","topicUid":"EchoHub.Server.Irc.IrcGatewayService","type":"Class"},{"name":"IrcMessage","href":"server-irc/EchoHub.Server.Irc.IrcMessage.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcMessage.html","topicUid":"EchoHub.Server.Irc.IrcMessage","type":"Class"},{"name":"IrcMessageFormatter","href":"server-irc/EchoHub.Server.Irc.IrcMessageFormatter.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcMessageFormatter.html","topicUid":"EchoHub.Server.Irc.IrcMessageFormatter","type":"Class"},{"name":"IrcNumericReply","href":"server-irc/EchoHub.Server.Irc.IrcNumericReply.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcNumericReply.html","topicUid":"EchoHub.Server.Irc.IrcNumericReply","type":"Class"},{"name":"IrcOptions","href":"server-irc/EchoHub.Server.Irc.IrcOptions.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcOptions.html","topicUid":"EchoHub.Server.Irc.IrcOptions","type":"Class"},{"name":"IrcServiceExtensions","href":"server-irc/EchoHub.Server.Irc.IrcServiceExtensions.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcServiceExtensions.html","topicUid":"EchoHub.Server.Irc.IrcServiceExtensions","type":"Class"}]}]}]}]} +{"items":[{"name":"Client","items":[{"name":"API Reference","includedFrom":"~/_api_meta/client/toc.yml","items":[{"name":"EchoHub.Client","href":"client/EchoHub.Client.html","topicHref":"client/EchoHub.Client.html","topicUid":"EchoHub.Client","type":"Namespace","items":[{"name":"AppOrchestrator","href":"client/EchoHub.Client.AppOrchestrator.html","topicHref":"client/EchoHub.Client.AppOrchestrator.html","topicUid":"EchoHub.Client.AppOrchestrator","type":"Class"},{"name":"AsyncRunner","href":"client/EchoHub.Client.AsyncRunner.html","topicHref":"client/EchoHub.Client.AsyncRunner.html","topicUid":"EchoHub.Client.AsyncRunner","type":"Class"}]},{"name":"EchoHub.Client.Commands","href":"client/EchoHub.Client.Commands.html","topicHref":"client/EchoHub.Client.Commands.html","topicUid":"EchoHub.Client.Commands","type":"Namespace","items":[{"name":"CommandHandler","href":"client/EchoHub.Client.Commands.CommandHandler.html","topicHref":"client/EchoHub.Client.Commands.CommandHandler.html","topicUid":"EchoHub.Client.Commands.CommandHandler","type":"Class"},{"name":"CommandResult","href":"client/EchoHub.Client.Commands.CommandResult.html","topicHref":"client/EchoHub.Client.Commands.CommandResult.html","topicUid":"EchoHub.Client.Commands.CommandResult","type":"Class"}]},{"name":"EchoHub.Client.Config","href":"client/EchoHub.Client.Config.html","topicHref":"client/EchoHub.Client.Config.html","topicUid":"EchoHub.Client.Config","type":"Namespace","items":[{"name":"AccountPreset","href":"client/EchoHub.Client.Config.AccountPreset.html","topicHref":"client/EchoHub.Client.Config.AccountPreset.html","topicUid":"EchoHub.Client.Config.AccountPreset","type":"Class"},{"name":"ClientConfig","href":"client/EchoHub.Client.Config.ClientConfig.html","topicHref":"client/EchoHub.Client.Config.ClientConfig.html","topicUid":"EchoHub.Client.Config.ClientConfig","type":"Class"},{"name":"ConfigManager","href":"client/EchoHub.Client.Config.ConfigManager.html","topicHref":"client/EchoHub.Client.Config.ConfigManager.html","topicUid":"EchoHub.Client.Config.ConfigManager","type":"Class"},{"name":"NotificationConfig","href":"client/EchoHub.Client.Config.NotificationConfig.html","topicHref":"client/EchoHub.Client.Config.NotificationConfig.html","topicUid":"EchoHub.Client.Config.NotificationConfig","type":"Class"},{"name":"SavedServer","href":"client/EchoHub.Client.Config.SavedServer.html","topicHref":"client/EchoHub.Client.Config.SavedServer.html","topicUid":"EchoHub.Client.Config.SavedServer","type":"Class"}]},{"name":"EchoHub.Client.Services","href":"client/EchoHub.Client.Services.html","topicHref":"client/EchoHub.Client.Services.html","topicUid":"EchoHub.Client.Services","type":"Namespace","items":[{"name":"ApiClient","href":"client/EchoHub.Client.Services.ApiClient.html","topicHref":"client/EchoHub.Client.Services.ApiClient.html","topicUid":"EchoHub.Client.Services.ApiClient","type":"Class"},{"name":"ClientEncryptionService","href":"client/EchoHub.Client.Services.ClientEncryptionService.html","topicHref":"client/EchoHub.Client.Services.ClientEncryptionService.html","topicUid":"EchoHub.Client.Services.ClientEncryptionService","type":"Class"},{"name":"EchoHubConnection","href":"client/EchoHub.Client.Services.EchoHubConnection.html","topicHref":"client/EchoHub.Client.Services.EchoHubConnection.html","topicUid":"EchoHub.Client.Services.EchoHubConnection","type":"Class"},{"name":"NotificationSoundService","href":"client/EchoHub.Client.Services.NotificationSoundService.html","topicHref":"client/EchoHub.Client.Services.NotificationSoundService.html","topicUid":"EchoHub.Client.Services.NotificationSoundService","type":"Class"},{"name":"UpdateChecker","href":"client/EchoHub.Client.Services.UpdateChecker.html","topicHref":"client/EchoHub.Client.Services.UpdateChecker.html","topicUid":"EchoHub.Client.Services.UpdateChecker","type":"Class"}]},{"name":"EchoHub.Client.Themes","href":"client/EchoHub.Client.Themes.html","topicHref":"client/EchoHub.Client.Themes.html","topicUid":"EchoHub.Client.Themes","type":"Namespace","items":[{"name":"Theme","href":"client/EchoHub.Client.Themes.Theme.html","topicHref":"client/EchoHub.Client.Themes.Theme.html","topicUid":"EchoHub.Client.Themes.Theme","type":"Class"},{"name":"ThemeColors","href":"client/EchoHub.Client.Themes.ThemeColors.html","topicHref":"client/EchoHub.Client.Themes.ThemeColors.html","topicUid":"EchoHub.Client.Themes.ThemeColors","type":"Class"},{"name":"ThemeManager","href":"client/EchoHub.Client.Themes.ThemeManager.html","topicHref":"client/EchoHub.Client.Themes.ThemeManager.html","topicUid":"EchoHub.Client.Themes.ThemeManager","type":"Class"}]},{"name":"EchoHub.Client.UI","href":"client/EchoHub.Client.UI.html","topicHref":"client/EchoHub.Client.UI.html","topicUid":"EchoHub.Client.UI","type":"Namespace","items":[{"name":"ChannelListSource","href":"client/EchoHub.Client.UI.ChannelListSource.html","topicHref":"client/EchoHub.Client.UI.ChannelListSource.html","topicUid":"EchoHub.Client.UI.ChannelListSource","type":"Class"},{"name":"ChatColors","href":"client/EchoHub.Client.UI.ChatColors.html","topicHref":"client/EchoHub.Client.UI.ChatColors.html","topicUid":"EchoHub.Client.UI.ChatColors","type":"Class"},{"name":"ChatLine","href":"client/EchoHub.Client.UI.ChatLine.html","topicHref":"client/EchoHub.Client.UI.ChatLine.html","topicUid":"EchoHub.Client.UI.ChatLine","type":"Class"},{"name":"ChatListSource","href":"client/EchoHub.Client.UI.ChatListSource.html","topicHref":"client/EchoHub.Client.UI.ChatListSource.html","topicUid":"EchoHub.Client.UI.ChatListSource","type":"Class"},{"name":"ChatSegment","href":"client/EchoHub.Client.UI.ChatSegment.html","topicHref":"client/EchoHub.Client.UI.ChatSegment.html","topicUid":"EchoHub.Client.UI.ChatSegment","type":"Class"},{"name":"ColorHelper","href":"client/EchoHub.Client.UI.ColorHelper.html","topicHref":"client/EchoHub.Client.UI.ColorHelper.html","topicUid":"EchoHub.Client.UI.ColorHelper","type":"Class"},{"name":"ConnectDialog","href":"client/EchoHub.Client.UI.ConnectDialog.html","topicHref":"client/EchoHub.Client.UI.ConnectDialog.html","topicUid":"EchoHub.Client.UI.ConnectDialog","type":"Class"},{"name":"ConnectDialogResult","href":"client/EchoHub.Client.UI.ConnectDialogResult.html","topicHref":"client/EchoHub.Client.UI.ConnectDialogResult.html","topicUid":"EchoHub.Client.UI.ConnectDialogResult","type":"Class"},{"name":"CreateChannelDialog","href":"client/EchoHub.Client.UI.CreateChannelDialog.html","topicHref":"client/EchoHub.Client.UI.CreateChannelDialog.html","topicUid":"EchoHub.Client.UI.CreateChannelDialog","type":"Class"},{"name":"CreateChannelResult","href":"client/EchoHub.Client.UI.CreateChannelResult.html","topicHref":"client/EchoHub.Client.UI.CreateChannelResult.html","topicUid":"EchoHub.Client.UI.CreateChannelResult","type":"Class"},{"name":"EmojiHelper","href":"client/EchoHub.Client.UI.EmojiHelper.html","topicHref":"client/EchoHub.Client.UI.EmojiHelper.html","topicUid":"EchoHub.Client.UI.EmojiHelper","type":"Class"},{"name":"MainWindow","href":"client/EchoHub.Client.UI.MainWindow.html","topicHref":"client/EchoHub.Client.UI.MainWindow.html","topicUid":"EchoHub.Client.UI.MainWindow","type":"Class"},{"name":"ProfileAction","href":"client/EchoHub.Client.UI.ProfileAction.html","topicHref":"client/EchoHub.Client.UI.ProfileAction.html","topicUid":"EchoHub.Client.UI.ProfileAction","type":"Enum"},{"name":"ProfileEditDialog","href":"client/EchoHub.Client.UI.ProfileEditDialog.html","topicHref":"client/EchoHub.Client.UI.ProfileEditDialog.html","topicUid":"EchoHub.Client.UI.ProfileEditDialog","type":"Class"},{"name":"ProfileEditResult","href":"client/EchoHub.Client.UI.ProfileEditResult.html","topicHref":"client/EchoHub.Client.UI.ProfileEditResult.html","topicUid":"EchoHub.Client.UI.ProfileEditResult","type":"Class"},{"name":"ProfileViewDialog","href":"client/EchoHub.Client.UI.ProfileViewDialog.html","topicHref":"client/EchoHub.Client.UI.ProfileViewDialog.html","topicUid":"EchoHub.Client.UI.ProfileViewDialog","type":"Class"},{"name":"StatusDialog","href":"client/EchoHub.Client.UI.StatusDialog.html","topicHref":"client/EchoHub.Client.UI.StatusDialog.html","topicUid":"EchoHub.Client.UI.StatusDialog","type":"Class"},{"name":"StatusDialogResult","href":"client/EchoHub.Client.UI.StatusDialogResult.html","topicHref":"client/EchoHub.Client.UI.StatusDialogResult.html","topicUid":"EchoHub.Client.UI.StatusDialogResult","type":"Class"},{"name":"UserListSource","href":"client/EchoHub.Client.UI.UserListSource.html","topicHref":"client/EchoHub.Client.UI.UserListSource.html","topicUid":"EchoHub.Client.UI.UserListSource","type":"Class"}]}]},{"name":"Articles","includedFrom":"~/api/client-articles/toc.yml","items":[{"name":"Overview","href":"client-articles/index.html","topicHref":"client-articles/index.html"}]}]},{"name":"Core","items":[{"name":"API Reference","includedFrom":"~/_api_meta/core/toc.yml","items":[{"name":"EchoHub.Core.Constants","href":"core/EchoHub.Core.Constants.html","topicHref":"core/EchoHub.Core.Constants.html","topicUid":"EchoHub.Core.Constants","type":"Namespace","items":[{"name":"HubConstants","href":"core/EchoHub.Core.Constants.HubConstants.html","topicHref":"core/EchoHub.Core.Constants.HubConstants.html","topicUid":"EchoHub.Core.Constants.HubConstants","type":"Class"},{"name":"ValidationConstants","href":"core/EchoHub.Core.Constants.ValidationConstants.html","topicHref":"core/EchoHub.Core.Constants.ValidationConstants.html","topicUid":"EchoHub.Core.Constants.ValidationConstants","type":"Class"}]},{"name":"EchoHub.Core.Contracts","href":"core/EchoHub.Core.Contracts.html","topicHref":"core/EchoHub.Core.Contracts.html","topicUid":"EchoHub.Core.Contracts","type":"Namespace","items":[{"name":"ChannelListItem","href":"core/EchoHub.Core.Contracts.ChannelListItem.html","topicHref":"core/EchoHub.Core.Contracts.ChannelListItem.html","topicUid":"EchoHub.Core.Contracts.ChannelListItem","type":"Class"},{"name":"IChatBroadcaster","href":"core/EchoHub.Core.Contracts.IChatBroadcaster.html","topicHref":"core/EchoHub.Core.Contracts.IChatBroadcaster.html","topicUid":"EchoHub.Core.Contracts.IChatBroadcaster","type":"Interface"},{"name":"IChatService","href":"core/EchoHub.Core.Contracts.IChatService.html","topicHref":"core/EchoHub.Core.Contracts.IChatService.html","topicUid":"EchoHub.Core.Contracts.IChatService","type":"Interface"},{"name":"IEchoHubClient","href":"core/EchoHub.Core.Contracts.IEchoHubClient.html","topicHref":"core/EchoHub.Core.Contracts.IEchoHubClient.html","topicUid":"EchoHub.Core.Contracts.IEchoHubClient","type":"Interface"},{"name":"IMessageEncryptionService","href":"core/EchoHub.Core.Contracts.IMessageEncryptionService.html","topicHref":"core/EchoHub.Core.Contracts.IMessageEncryptionService.html","topicUid":"EchoHub.Core.Contracts.IMessageEncryptionService","type":"Interface"}]},{"name":"EchoHub.Core.DTOs","href":"core/EchoHub.Core.DTOs.html","topicHref":"core/EchoHub.Core.DTOs.html","topicUid":"EchoHub.Core.DTOs","type":"Namespace","items":[{"name":"AssignRoleRequest","href":"core/EchoHub.Core.DTOs.AssignRoleRequest.html","topicHref":"core/EchoHub.Core.DTOs.AssignRoleRequest.html","topicUid":"EchoHub.Core.DTOs.AssignRoleRequest","type":"Class"},{"name":"AvatarUploadResponse","href":"core/EchoHub.Core.DTOs.AvatarUploadResponse.html","topicHref":"core/EchoHub.Core.DTOs.AvatarUploadResponse.html","topicUid":"EchoHub.Core.DTOs.AvatarUploadResponse","type":"Class"},{"name":"BanRequest","href":"core/EchoHub.Core.DTOs.BanRequest.html","topicHref":"core/EchoHub.Core.DTOs.BanRequest.html","topicUid":"EchoHub.Core.DTOs.BanRequest","type":"Class"},{"name":"ChannelDto","href":"core/EchoHub.Core.DTOs.ChannelDto.html","topicHref":"core/EchoHub.Core.DTOs.ChannelDto.html","topicUid":"EchoHub.Core.DTOs.ChannelDto","type":"Class"},{"name":"CreateChannelRequest","href":"core/EchoHub.Core.DTOs.CreateChannelRequest.html","topicHref":"core/EchoHub.Core.DTOs.CreateChannelRequest.html","topicUid":"EchoHub.Core.DTOs.CreateChannelRequest","type":"Class"},{"name":"EmbedDto","href":"core/EchoHub.Core.DTOs.EmbedDto.html","topicHref":"core/EchoHub.Core.DTOs.EmbedDto.html","topicUid":"EchoHub.Core.DTOs.EmbedDto","type":"Class"},{"name":"EncryptionKeyResponse","href":"core/EchoHub.Core.DTOs.EncryptionKeyResponse.html","topicHref":"core/EchoHub.Core.DTOs.EncryptionKeyResponse.html","topicUid":"EchoHub.Core.DTOs.EncryptionKeyResponse","type":"Class"},{"name":"ErrorResponse","href":"core/EchoHub.Core.DTOs.ErrorResponse.html","topicHref":"core/EchoHub.Core.DTOs.ErrorResponse.html","topicUid":"EchoHub.Core.DTOs.ErrorResponse","type":"Class"},{"name":"KickRequest","href":"core/EchoHub.Core.DTOs.KickRequest.html","topicHref":"core/EchoHub.Core.DTOs.KickRequest.html","topicUid":"EchoHub.Core.DTOs.KickRequest","type":"Class"},{"name":"LoginRequest","href":"core/EchoHub.Core.DTOs.LoginRequest.html","topicHref":"core/EchoHub.Core.DTOs.LoginRequest.html","topicUid":"EchoHub.Core.DTOs.LoginRequest","type":"Class"},{"name":"LoginResponse","href":"core/EchoHub.Core.DTOs.LoginResponse.html","topicHref":"core/EchoHub.Core.DTOs.LoginResponse.html","topicUid":"EchoHub.Core.DTOs.LoginResponse","type":"Class"},{"name":"MessageDto","href":"core/EchoHub.Core.DTOs.MessageDto.html","topicHref":"core/EchoHub.Core.DTOs.MessageDto.html","topicUid":"EchoHub.Core.DTOs.MessageDto","type":"Class"},{"name":"MuteRequest","href":"core/EchoHub.Core.DTOs.MuteRequest.html","topicHref":"core/EchoHub.Core.DTOs.MuteRequest.html","topicUid":"EchoHub.Core.DTOs.MuteRequest","type":"Class"},{"name":"PaginatedResponse","href":"core/EchoHub.Core.DTOs.PaginatedResponse-1.html","topicHref":"core/EchoHub.Core.DTOs.PaginatedResponse-1.html","topicUid":"EchoHub.Core.DTOs.PaginatedResponse`1","type":"Class"},{"name":"RefreshRequest","href":"core/EchoHub.Core.DTOs.RefreshRequest.html","topicHref":"core/EchoHub.Core.DTOs.RefreshRequest.html","topicUid":"EchoHub.Core.DTOs.RefreshRequest","type":"Class"},{"name":"RegisterRequest","href":"core/EchoHub.Core.DTOs.RegisterRequest.html","topicHref":"core/EchoHub.Core.DTOs.RegisterRequest.html","topicUid":"EchoHub.Core.DTOs.RegisterRequest","type":"Class"},{"name":"SendMessageRequest","href":"core/EchoHub.Core.DTOs.SendMessageRequest.html","topicHref":"core/EchoHub.Core.DTOs.SendMessageRequest.html","topicUid":"EchoHub.Core.DTOs.SendMessageRequest","type":"Class"},{"name":"SendUrlRequest","href":"core/EchoHub.Core.DTOs.SendUrlRequest.html","topicHref":"core/EchoHub.Core.DTOs.SendUrlRequest.html","topicUid":"EchoHub.Core.DTOs.SendUrlRequest","type":"Class"},{"name":"ServerStatusDto","href":"core/EchoHub.Core.DTOs.ServerStatusDto.html","topicHref":"core/EchoHub.Core.DTOs.ServerStatusDto.html","topicUid":"EchoHub.Core.DTOs.ServerStatusDto","type":"Class"},{"name":"UpdateProfileRequest","href":"core/EchoHub.Core.DTOs.UpdateProfileRequest.html","topicHref":"core/EchoHub.Core.DTOs.UpdateProfileRequest.html","topicUid":"EchoHub.Core.DTOs.UpdateProfileRequest","type":"Class"},{"name":"UpdateStatusRequest","href":"core/EchoHub.Core.DTOs.UpdateStatusRequest.html","topicHref":"core/EchoHub.Core.DTOs.UpdateStatusRequest.html","topicUid":"EchoHub.Core.DTOs.UpdateStatusRequest","type":"Class"},{"name":"UpdateTopicRequest","href":"core/EchoHub.Core.DTOs.UpdateTopicRequest.html","topicHref":"core/EchoHub.Core.DTOs.UpdateTopicRequest.html","topicUid":"EchoHub.Core.DTOs.UpdateTopicRequest","type":"Class"},{"name":"UserDto","href":"core/EchoHub.Core.DTOs.UserDto.html","topicHref":"core/EchoHub.Core.DTOs.UserDto.html","topicUid":"EchoHub.Core.DTOs.UserDto","type":"Class"},{"name":"UserPresenceDto","href":"core/EchoHub.Core.DTOs.UserPresenceDto.html","topicHref":"core/EchoHub.Core.DTOs.UserPresenceDto.html","topicUid":"EchoHub.Core.DTOs.UserPresenceDto","type":"Class"},{"name":"UserProfileDto","href":"core/EchoHub.Core.DTOs.UserProfileDto.html","topicHref":"core/EchoHub.Core.DTOs.UserProfileDto.html","topicUid":"EchoHub.Core.DTOs.UserProfileDto","type":"Class"}]},{"name":"EchoHub.Core.Models","href":"core/EchoHub.Core.Models.html","topicHref":"core/EchoHub.Core.Models.html","topicUid":"EchoHub.Core.Models","type":"Namespace","items":[{"name":"Channel","href":"core/EchoHub.Core.Models.Channel.html","topicHref":"core/EchoHub.Core.Models.Channel.html","topicUid":"EchoHub.Core.Models.Channel","type":"Class"},{"name":"ChannelMembership","href":"core/EchoHub.Core.Models.ChannelMembership.html","topicHref":"core/EchoHub.Core.Models.ChannelMembership.html","topicUid":"EchoHub.Core.Models.ChannelMembership","type":"Class"},{"name":"Message","href":"core/EchoHub.Core.Models.Message.html","topicHref":"core/EchoHub.Core.Models.Message.html","topicUid":"EchoHub.Core.Models.Message","type":"Class"},{"name":"MessageType","href":"core/EchoHub.Core.Models.MessageType.html","topicHref":"core/EchoHub.Core.Models.MessageType.html","topicUid":"EchoHub.Core.Models.MessageType","type":"Enum"},{"name":"RefreshToken","href":"core/EchoHub.Core.Models.RefreshToken.html","topicHref":"core/EchoHub.Core.Models.RefreshToken.html","topicUid":"EchoHub.Core.Models.RefreshToken","type":"Class"},{"name":"ServerRole","href":"core/EchoHub.Core.Models.ServerRole.html","topicHref":"core/EchoHub.Core.Models.ServerRole.html","topicUid":"EchoHub.Core.Models.ServerRole","type":"Enum"},{"name":"User","href":"core/EchoHub.Core.Models.User.html","topicHref":"core/EchoHub.Core.Models.User.html","topicUid":"EchoHub.Core.Models.User","type":"Class"},{"name":"UserStatus","href":"core/EchoHub.Core.Models.UserStatus.html","topicHref":"core/EchoHub.Core.Models.UserStatus.html","topicUid":"EchoHub.Core.Models.UserStatus","type":"Enum"}]}]},{"name":"Articles","includedFrom":"~/api/core-articles/toc.yml","items":[{"name":"Overview","href":"core-articles/index.html","topicHref":"core-articles/index.html"}]}]},{"name":"Server","items":[{"name":"API Reference","includedFrom":"~/_api_meta/server/toc.yml","items":[{"name":"EchoHub.Server.Auth","href":"server/EchoHub.Server.Auth.html","topicHref":"server/EchoHub.Server.Auth.html","topicUid":"EchoHub.Server.Auth","type":"Namespace","items":[{"name":"JwtTokenService","href":"server/EchoHub.Server.Auth.JwtTokenService.html","topicHref":"server/EchoHub.Server.Auth.JwtTokenService.html","topicUid":"EchoHub.Server.Auth.JwtTokenService","type":"Class"}]},{"name":"EchoHub.Server.Controllers","href":"server/EchoHub.Server.Controllers.html","topicHref":"server/EchoHub.Server.Controllers.html","topicUid":"EchoHub.Server.Controllers","type":"Namespace","items":[{"name":"AuthController","href":"server/EchoHub.Server.Controllers.AuthController.html","topicHref":"server/EchoHub.Server.Controllers.AuthController.html","topicUid":"EchoHub.Server.Controllers.AuthController","type":"Class"},{"name":"ChannelsController","href":"server/EchoHub.Server.Controllers.ChannelsController.html","topicHref":"server/EchoHub.Server.Controllers.ChannelsController.html","topicUid":"EchoHub.Server.Controllers.ChannelsController","type":"Class"},{"name":"FilesController","href":"server/EchoHub.Server.Controllers.FilesController.html","topicHref":"server/EchoHub.Server.Controllers.FilesController.html","topicUid":"EchoHub.Server.Controllers.FilesController","type":"Class"},{"name":"ModerationController","href":"server/EchoHub.Server.Controllers.ModerationController.html","topicHref":"server/EchoHub.Server.Controllers.ModerationController.html","topicUid":"EchoHub.Server.Controllers.ModerationController","type":"Class"},{"name":"ServerController","href":"server/EchoHub.Server.Controllers.ServerController.html","topicHref":"server/EchoHub.Server.Controllers.ServerController.html","topicUid":"EchoHub.Server.Controllers.ServerController","type":"Class"},{"name":"UsersController","href":"server/EchoHub.Server.Controllers.UsersController.html","topicHref":"server/EchoHub.Server.Controllers.UsersController.html","topicUid":"EchoHub.Server.Controllers.UsersController","type":"Class"}]},{"name":"EchoHub.Server.Data","href":"server/EchoHub.Server.Data.html","topicHref":"server/EchoHub.Server.Data.html","topicUid":"EchoHub.Server.Data","type":"Namespace","items":[{"name":"EchoHubDbContext","href":"server/EchoHub.Server.Data.EchoHubDbContext.html","topicHref":"server/EchoHub.Server.Data.EchoHubDbContext.html","topicUid":"EchoHub.Server.Data.EchoHubDbContext","type":"Class"}]},{"name":"EchoHub.Server.Data.Migrations","href":"server/EchoHub.Server.Data.Migrations.html","topicHref":"server/EchoHub.Server.Data.Migrations.html","topicUid":"EchoHub.Server.Data.Migrations","type":"Namespace","items":[{"name":"AddChannelIsPublic","href":"server/EchoHub.Server.Data.Migrations.AddChannelIsPublic.html","topicHref":"server/EchoHub.Server.Data.Migrations.AddChannelIsPublic.html","topicUid":"EchoHub.Server.Data.Migrations.AddChannelIsPublic","type":"Class"},{"name":"AddChannelMembership","href":"server/EchoHub.Server.Data.Migrations.AddChannelMembership.html","topicHref":"server/EchoHub.Server.Data.Migrations.AddChannelMembership.html","topicUid":"EchoHub.Server.Data.Migrations.AddChannelMembership","type":"Class"},{"name":"AddEncryptionSupport","href":"server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html","topicHref":"server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html","topicUid":"EchoHub.Server.Data.Migrations.AddEncryptionSupport","type":"Class"},{"name":"AddMessageEmbed","href":"server/EchoHub.Server.Data.Migrations.AddMessageEmbed.html","topicHref":"server/EchoHub.Server.Data.Migrations.AddMessageEmbed.html","topicUid":"EchoHub.Server.Data.Migrations.AddMessageEmbed","type":"Class"},{"name":"AddModerationRoles","href":"server/EchoHub.Server.Data.Migrations.AddModerationRoles.html","topicHref":"server/EchoHub.Server.Data.Migrations.AddModerationRoles.html","topicUid":"EchoHub.Server.Data.Migrations.AddModerationRoles","type":"Class"},{"name":"InitialCreate","href":"server/EchoHub.Server.Data.Migrations.InitialCreate.html","topicHref":"server/EchoHub.Server.Data.Migrations.InitialCreate.html","topicUid":"EchoHub.Server.Data.Migrations.InitialCreate","type":"Class"}]},{"name":"EchoHub.Server.Hubs","href":"server/EchoHub.Server.Hubs.html","topicHref":"server/EchoHub.Server.Hubs.html","topicUid":"EchoHub.Server.Hubs","type":"Namespace","items":[{"name":"ChatHub","href":"server/EchoHub.Server.Hubs.ChatHub.html","topicHref":"server/EchoHub.Server.Hubs.ChatHub.html","topicUid":"EchoHub.Server.Hubs.ChatHub","type":"Class"}]},{"name":"EchoHub.Server.Services","href":"server/EchoHub.Server.Services.html","topicHref":"server/EchoHub.Server.Services.html","topicUid":"EchoHub.Server.Services","type":"Namespace","items":[{"name":"ChatService","href":"server/EchoHub.Server.Services.ChatService.html","topicHref":"server/EchoHub.Server.Services.ChatService.html","topicUid":"EchoHub.Server.Services.ChatService","type":"Class"},{"name":"FileStorageService","href":"server/EchoHub.Server.Services.FileStorageService.html","topicHref":"server/EchoHub.Server.Services.FileStorageService.html","topicUid":"EchoHub.Server.Services.FileStorageService","type":"Class"},{"name":"FileValidationHelper","href":"server/EchoHub.Server.Services.FileValidationHelper.html","topicHref":"server/EchoHub.Server.Services.FileValidationHelper.html","topicUid":"EchoHub.Server.Services.FileValidationHelper","type":"Class"},{"name":"ImageToAsciiService","href":"server/EchoHub.Server.Services.ImageToAsciiService.html","topicHref":"server/EchoHub.Server.Services.ImageToAsciiService.html","topicUid":"EchoHub.Server.Services.ImageToAsciiService","type":"Class"},{"name":"LinkEmbedService","href":"server/EchoHub.Server.Services.LinkEmbedService.html","topicHref":"server/EchoHub.Server.Services.LinkEmbedService.html","topicUid":"EchoHub.Server.Services.LinkEmbedService","type":"Class"},{"name":"MessageEncryptionService","href":"server/EchoHub.Server.Services.MessageEncryptionService.html","topicHref":"server/EchoHub.Server.Services.MessageEncryptionService.html","topicUid":"EchoHub.Server.Services.MessageEncryptionService","type":"Class"},{"name":"PresenceTracker","href":"server/EchoHub.Server.Services.PresenceTracker.html","topicHref":"server/EchoHub.Server.Services.PresenceTracker.html","topicUid":"EchoHub.Server.Services.PresenceTracker","type":"Class"},{"name":"ServerDirectoryService","href":"server/EchoHub.Server.Services.ServerDirectoryService.html","topicHref":"server/EchoHub.Server.Services.ServerDirectoryService.html","topicUid":"EchoHub.Server.Services.ServerDirectoryService","type":"Class"},{"name":"SignalRBroadcaster","href":"server/EchoHub.Server.Services.SignalRBroadcaster.html","topicHref":"server/EchoHub.Server.Services.SignalRBroadcaster.html","topicUid":"EchoHub.Server.Services.SignalRBroadcaster","type":"Class"}]},{"name":"EchoHub.Server.Setup","href":"server/EchoHub.Server.Setup.html","topicHref":"server/EchoHub.Server.Setup.html","topicUid":"EchoHub.Server.Setup","type":"Namespace","items":[{"name":"DataMigrationService","href":"server/EchoHub.Server.Setup.DataMigrationService.html","topicHref":"server/EchoHub.Server.Setup.DataMigrationService.html","topicUid":"EchoHub.Server.Setup.DataMigrationService","type":"Class"},{"name":"DatabaseSetup","href":"server/EchoHub.Server.Setup.DatabaseSetup.html","topicHref":"server/EchoHub.Server.Setup.DatabaseSetup.html","topicUid":"EchoHub.Server.Setup.DatabaseSetup","type":"Class"},{"name":"FirstRunSetup","href":"server/EchoHub.Server.Setup.FirstRunSetup.html","topicHref":"server/EchoHub.Server.Setup.FirstRunSetup.html","topicUid":"EchoHub.Server.Setup.FirstRunSetup","type":"Class"}]}]},{"name":"Articles","includedFrom":"~/api/server-articles/toc.yml","items":[{"name":"Overview","href":"server-articles/index.html","topicHref":"server-articles/index.html"}]}]},{"name":"Server.Irc","items":[{"name":"API Reference","includedFrom":"~/_api_meta/server-irc/toc.yml","items":[{"name":"EchoHub.Server.Irc","href":"server-irc/EchoHub.Server.Irc.html","topicHref":"server-irc/EchoHub.Server.Irc.html","topicUid":"EchoHub.Server.Irc","type":"Namespace","items":[{"name":"IrcBroadcaster","href":"server-irc/EchoHub.Server.Irc.IrcBroadcaster.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcBroadcaster.html","topicUid":"EchoHub.Server.Irc.IrcBroadcaster","type":"Class"},{"name":"IrcClientConnection","href":"server-irc/EchoHub.Server.Irc.IrcClientConnection.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcClientConnection.html","topicUid":"EchoHub.Server.Irc.IrcClientConnection","type":"Class"},{"name":"IrcCommandHandler","href":"server-irc/EchoHub.Server.Irc.IrcCommandHandler.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcCommandHandler.html","topicUid":"EchoHub.Server.Irc.IrcCommandHandler","type":"Class"},{"name":"IrcGatewayService","href":"server-irc/EchoHub.Server.Irc.IrcGatewayService.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcGatewayService.html","topicUid":"EchoHub.Server.Irc.IrcGatewayService","type":"Class"},{"name":"IrcMessage","href":"server-irc/EchoHub.Server.Irc.IrcMessage.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcMessage.html","topicUid":"EchoHub.Server.Irc.IrcMessage","type":"Class"},{"name":"IrcMessageFormatter","href":"server-irc/EchoHub.Server.Irc.IrcMessageFormatter.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcMessageFormatter.html","topicUid":"EchoHub.Server.Irc.IrcMessageFormatter","type":"Class"},{"name":"IrcNumericReply","href":"server-irc/EchoHub.Server.Irc.IrcNumericReply.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcNumericReply.html","topicUid":"EchoHub.Server.Irc.IrcNumericReply","type":"Class"},{"name":"IrcOptions","href":"server-irc/EchoHub.Server.Irc.IrcOptions.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcOptions.html","topicUid":"EchoHub.Server.Irc.IrcOptions","type":"Class"},{"name":"IrcServiceExtensions","href":"server-irc/EchoHub.Server.Irc.IrcServiceExtensions.html","topicHref":"server-irc/EchoHub.Server.Irc.IrcServiceExtensions.html","topicUid":"EchoHub.Server.Irc.IrcServiceExtensions","type":"Class"}]}]}]}]} diff --git a/articles/encryption.html b/articles/encryption.html new file mode 100644 index 0000000..eda13fb --- /dev/null +++ b/articles/encryption.html @@ -0,0 +1,243 @@ + + + + + Message Encryption | EchoHub Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +
    +
    +
    +
    +
    Table of Contents
    + +
    +
    + +
    +
    +
    + +
    +
    + + + +
    + +
    +

    Message Encryption

    + +

    EchoHub uses application-layer AES-256-GCM encryption to protect message content in transit between clients and the server. This is an additional layer on top of TLS, protecting against ISPs, proxies, and any middleman that can inspect HTTPS traffic (e.g. corporate proxies with trusted root CA certificates).

    +

    How It Works

    +
    sequenceDiagram
    +    participant Sender as TUI Client (Sender)
    +    participant Server
    +    participant Receiver as TUI Client (Receiver)
    +    participant IRC as IRC Client
    +
    +    Sender->>Sender: encrypt(plaintext)
    +    Sender->>Server: $ENC$v1$... (SignalR)
    +    Server->>Server: decrypt → validate/sanitize
    +    Server->>Server: fetch embeds on plaintext
    +    Server->>Server: (optional) encrypt for DB storage
    +    Server->>Server: encrypt(plaintext) with fresh nonce
    +    Server->>Receiver: $ENC$v1$... (SignalR broadcast)
    +    Receiver->>Receiver: decrypt → display
    +    Server->>Server: decrypt for IRC
    +    Server->>IRC: plaintext (IRC PRIVMSG)
    +
    +
      +
    1. Client encrypts the message before sending it over SignalR
    2. +
    3. Server decrypts to validate content, sanitize newlines, and fetch link embeds
    4. +
    5. Server re-encrypts with a fresh nonce and broadcasts to all connected SignalR clients
    6. +
    7. Clients decrypt the broadcast and display the plaintext
    8. +
    9. IRC clients receive plaintext automatically (the IRC broadcaster decrypts before forwarding)
    10. +
    +

    Each encryption uses a random 12-byte nonce, so the same message produces different ciphertext every time.

    +

    Encryption Key

    +

    A 256-bit AES key is auto-generated on first server startup and saved to appsettings.json:

    +
    {
    +  "Encryption": {
    +    "Key": "base64-encoded-32-byte-key",
    +    "EncryptDatabase": false
    +  }
    +}
    +
    +

    The key is generated by FirstRunSetup using RandomNumberGenerator.GetBytes(32). If the key is missing or empty when the server starts, a new one is created automatically.

    +

    Clients fetch the key after login via an authenticated endpoint (GET /api/server/encryption-key). No manual configuration is needed on the client side.

    +

    Encrypted Content Format

    +

    Encrypted content uses a self-describing format:

    +
    $ENC$v1${nonce_base64}${ciphertext+tag_base64}
    +
    +
      +
    • $ENC$v1$ — version prefix (allows future algorithm changes)
    • +
    • Nonce — 12 bytes, Base64-encoded, randomly generated per message
    • +
    • Ciphertext + Tag — AES-256-GCM output with 16-byte authentication tag appended
    • +
    +

    The authentication tag ensures both confidentiality and integrity — any tampering with the ciphertext is detected during decryption.

    +

    Database Encryption (Optional)

    +

    By default, messages are stored as plaintext in the database. Transport encryption still protects everything on the wire, but the SQLite file itself contains readable messages.

    +

    To encrypt messages at rest, enable the setting:

    +
    {
    +  "Encryption": {
    +    "Key": "...",
    +    "EncryptDatabase": true
    +  }
    +}
    +
    +

    Behavior by Setting

    + + + + + + + + + + + + + + + + + + + + + + + +
    SettingDB StorageTransportKey Rotation Risk
    false (default)PlaintextEncryptedNone - stored data is unaffected
    trueEncryptedEncryptedChanging the key makes old messages unreadable
    +

    Mixed Content

    +

    The server handles mixed encrypted/plaintext content in the database gracefully. When reading messages:

    +
      +
    • Content starting with $ENC$v1$ is decrypted
    • +
    • Everything else is treated as plaintext
    • +
    +

    This means you can safely toggle EncryptDatabase at any time. Old messages remain readable regardless of the current setting.

    +

    Enabling Encryption at Rest

    +

    When you set EncryptDatabase: true, only new messages are encrypted going forward. Existing plaintext messages in the database are not retroactively encrypted. This is intentional — it keeps key rotation safe and avoids irreversible bulk changes.

    +

    Key Rotation

    +

    Changing the encryption key is safe:

    +
      +
    • Plaintext messages — always readable regardless of key
    • +
    • Messages encrypted with the old key — will show [encrypted message — decryption failed]
    • +
    • New messages — encrypted with the new key going forward
    • +
    +

    If you need to recover old encrypted messages, restore the original key from a backup of appsettings.json. Since plaintext messages are never retroactively encrypted, you'll never lose access to your entire history from a key change.

    +

    Security Considerations

    +

    What This Protects Against

    +
      +
    • Passive network sniffing — messages are encrypted even if captured off the wire
    • +
    • ISP/proxy inspection — content is encrypted at the application layer, independent of TLS
    • +
    • Database theft (when EncryptDatabase: true) — SQLite file contains only ciphertext
    • +
    +

    Limitations

    +
      +
    • TLS-inspecting proxies — if a corporate proxy terminates TLS with a trusted root CA, it can intercept the key exchange (GET /api/server/encryption-key) and read all traffic. A future upgrade to ECDH key exchange would address this.
    • +
    • Server has full access — the server decrypts all messages for processing. This is not end-to-end encryption between users; it's transport encryption between client and server.
    • +
    • IRC clients receive plaintext — IRC is an open protocol and third-party clients cannot participate in the encryption scheme.
    • +
    +

    Troubleshooting

    +

    Messages show [encrypted message — decryption failed, try re-logging to fetch the latest key]

    +

    The client's encryption key doesn't match the server's. This happens when:

    +
      +
    • The server's encryption key was rotated while the client was connected
    • +
    • The client cached a stale key
    • +
    +

    Fix: Disconnect and reconnect (re-login). The client fetches the current key on each login.

    +

    Messages show [encrypted message — decryption failed] in channel history

    +

    The server cannot decrypt messages stored in the database. This happens when:

    +
      +
    • EncryptDatabase was enabled, and the key was changed afterwards
    • +
    +

    Fix: Restore the original key from a backup. There is no way to recover messages encrypted with a lost key.

    + +
    + + + + + +
    + +
    + +
    +
    + +
    + + + + diff --git a/articles/toc.html b/articles/toc.html index bde8672..24ef3fa 100644 --- a/articles/toc.html +++ b/articles/toc.html @@ -18,6 +18,12 @@
  • Architecture
  • +
  • + Encryption +
  • +
  • + Notification Sounds +
  • diff --git a/articles/toc.json b/articles/toc.json index d3274ff..627b95f 100644 --- a/articles/toc.json +++ b/articles/toc.json @@ -1,2 +1,2 @@ -{"items":[{"name":"Getting Started","href":"getting-started.html","topicHref":"getting-started.html"},{"name":"Architecture","href":"architecture.html","topicHref":"architecture.html"}]} +{"items":[{"name":"Getting Started","href":"getting-started.html","topicHref":"getting-started.html"},{"name":"Architecture","href":"architecture.html","topicHref":"architecture.html"},{"name":"Encryption","href":"encryption.html","topicHref":"encryption.html"},{"name":"Notification Sounds","href":"notification-sounds.html","topicHref":"notification-sounds.html"}]} diff --git a/changelog/toc.html b/changelog/toc.html index 822b780..fbc7369 100644 --- a/changelog/toc.html +++ b/changelog/toc.html @@ -15,6 +15,9 @@
  • Overview
  • +
  • + v0.2.4 +
  • v0.2.3
  • diff --git a/changelog/toc.json b/changelog/toc.json index 801cbcb..e095da8 100644 --- a/changelog/toc.json +++ b/changelog/toc.json @@ -1,2 +1,2 @@ -{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"v0.2.3","href":"v0.2.3.html","topicHref":"v0.2.3.html"},{"name":"v0.2.2","href":"v0.2.2.html","topicHref":"v0.2.2.html"},{"name":"v0.2.1","href":"v0.2.1.html","topicHref":"v0.2.1.html"},{"name":"v0.2.0","href":"v0.2.0.html","topicHref":"v0.2.0.html"},{"name":"v0.1.1","href":"v0.1.1.html","topicHref":"v0.1.1.html"},{"name":"v0.1.0","href":"v0.1.0.html","topicHref":"v0.1.0.html"}]} +{"items":[{"name":"Overview","href":"index.html","topicHref":"index.html"},{"name":"v0.2.4","href":"v0.2.4.html","topicHref":"v0.2.4.html"},{"name":"v0.2.3","href":"v0.2.3.html","topicHref":"v0.2.3.html"},{"name":"v0.2.2","href":"v0.2.2.html","topicHref":"v0.2.2.html"},{"name":"v0.2.1","href":"v0.2.1.html","topicHref":"v0.2.1.html"},{"name":"v0.2.0","href":"v0.2.0.html","topicHref":"v0.2.0.html"},{"name":"v0.1.1","href":"v0.1.1.html","topicHref":"v0.1.1.html"},{"name":"v0.1.0","href":"v0.1.0.html","topicHref":"v0.1.0.html"}]} diff --git a/changelog/v0.2.4.html b/changelog/v0.2.4.html new file mode 100644 index 0000000..4acb041 --- /dev/null +++ b/changelog/v0.2.4.html @@ -0,0 +1,149 @@ + + + + + v0.2.4 - E2E Message Encryption | EchoHub Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +
    +
    +
    +
    +
    Table of Contents
    + +
    +
    + +
    +
    +
    + +
    +
    + + + +
    + +
    +

    v0.2.4 - E2E Message Encryption

    + +

    Features

    +

    E2E Message Encryption

    +
      +
    • Application-layer AES-256-GCM encryption for all message content between client and server
    • +
    • Protects against ISPs, proxies, and any middleman reading chat messages — even if TLS is compromised
    • +
    • 256-bit encryption key auto-generated on first server startup and saved to appsettings.json
    • +
    • Client fetches the encryption key automatically after login via GET /api/server/encryption-key
    • +
    • Client encrypts messages before sending via SignalR; server decrypts for validation and processing
    • +
    • Server broadcasts encrypted content to SignalR clients; client decrypts transparently — no user action required
    • +
    • Optional database encryption at rest via Encryption:EncryptDatabase setting (disabled by default) +
        +
      • When enabled: new messages encrypted before DB storage (existing plaintext messages are not retroactively encrypted)
      • +
      • When disabled: messages stored as plaintext, no risk of data loss from key rotation
      • +
      • Reads handle mixed content (encrypted + plaintext) regardless of setting — safe to toggle at any time
      • +
      • Key rotation is safe: old plaintext stays readable, new messages use the new key
      • +
      +
    • +
    • IRC gateway automatically decrypts messages before forwarding to IRC clients (plaintext over IRC)
    • +
    • Encrypted content format: $ENC$v1${nonce}${ciphertext+tag} (Base64, 12-byte nonce, 16-byte auth tag)
    • +
    • Server strips $ENC$ prefix from user-typed messages to prevent format spoofing
    • +
    • Graceful fallback: if decryption fails, shows [encrypted message — decryption failed, try re-logging to fetch the latest key]
    • +
    +

    Infrastructure

    +
      +
    • IMessageEncryptionService interface in Core; MessageEncryptionService server implementation and ClientEncryptionService client implementation
    • +
    • EncryptionKeyResponse DTO and GET /api/server/encryption-key endpoint (authenticated, rate-limited)
    • +
    • FirstRunSetup.EnsureEncryptionKey() auto-generates AES-256 key on first server run
    • +
    • Encryption:EncryptDatabase server setting (default false) controls whether messages are encrypted at rest
    • +
    • DB column max lengths increased for encrypted content: Message.Content 2000 → 16000, Message.EmbedJson 8000 → 32000
    • +
    • EF Core migration: AddEncryptionSupport
    • +
    • Encryption test suite: server-side, client-side, and cross-compatibility tests (87 total)
    • +
    • Documentation article: docs/articles/encryption.md
    • +
    + +
    + + + + + +
    + +
    + +
    +
    + +
    + + + + diff --git a/index.json b/index.json index beeb57c..468d447 100644 --- a/index.json +++ b/index.json @@ -62,12 +62,17 @@ "api/client/EchoHub.Client.Services.ApiClient.html": { "href": "api/client/EchoHub.Client.Services.ApiClient.html", "title": "Class ApiClient | EchoHub Documentation", - "summary": "Class ApiClient Namespace EchoHub.Client.Services Assembly EchoHub.Client.dll public sealed class ApiClient : IDisposable Inheritance object ApiClient Implements IDisposable Inherited Members object.GetType() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors ApiClient(string) public ApiClient(string baseUrl) Parameters baseUrl string Properties BaseUrl public string BaseUrl { get; } Property Value string RefreshToken public string? RefreshToken { get; } Property Value string Token public string? Token { get; } Property Value string Methods AssignRoleAsync(string, ServerRole) public Task AssignRoleAsync(string username, ServerRole role) Parameters username string role ServerRole Returns Task BanUserAsync(string, string?) public Task BanUserAsync(string username, string? reason = null) Parameters username string reason string Returns Task CreateChannelAsync(string, string?, bool) public Task CreateChannelAsync(string name, string? topic = null, bool isPublic = true) Parameters name string topic string isPublic bool Returns Task DeleteChannelAsync(string) public Task DeleteChannelAsync(string channelName) Parameters channelName string Returns Task DeleteMessageAsync(Guid) public Task DeleteMessageAsync(Guid messageId) Parameters messageId Guid Returns Task Dispose() public void Dispose() GetChannelsAsync() public Task> GetChannelsAsync() Returns Task> GetServerInfoAsync() public Task GetServerInfoAsync() Returns Task GetUserProfileAsync(string) public Task GetUserProfileAsync(string username) Parameters username string Returns Task GetValidTokenAsync() Returns a valid access token, refreshing if expired. Used by EchoHubConnection for SignalR token provider. public Task GetValidTokenAsync() Returns Task KickUserAsync(string, string?) public Task KickUserAsync(string username, string? reason = null) Parameters username string reason string Returns Task LoginAsync(string, string) public Task LoginAsync(string username, string password) Parameters username string password string Returns Task LogoutAsync() public Task LogoutAsync() Returns Task MuteUserAsync(string, int?, string?) public Task MuteUserAsync(string username, int? durationMinutes = null, string? reason = null) Parameters username string durationMinutes int? reason string Returns Task NukeChannelAsync(string) public Task NukeChannelAsync(string channelName) Parameters channelName string Returns Task RefreshTokenAsync() public Task RefreshTokenAsync() Returns Task RegisterAsync(string, string, string?) public Task RegisterAsync(string username, string password, string? displayName = null) Parameters username string password string displayName string Returns Task SendUrlAsync(string, string, string?) public Task SendUrlAsync(string channelName, string url, string? size = null) Parameters channelName string url string size string Returns Task UnbanUserAsync(string) public Task UnbanUserAsync(string username) Parameters username string Returns Task UnmuteUserAsync(string) public Task UnmuteUserAsync(string username) Parameters username string Returns Task UpdateChannelTopicAsync(string, string?) public Task UpdateChannelTopicAsync(string channelName, string? topic) Parameters channelName string topic string Returns Task UpdateProfileAsync(UpdateProfileRequest) public Task UpdateProfileAsync(UpdateProfileRequest request) Parameters request UpdateProfileRequest Returns Task UploadAvatarAsync(Stream, string) public Task UploadAvatarAsync(Stream imageStream, string fileName) Parameters imageStream Stream fileName string Returns Task UploadFileAsync(string, Stream, string, string?) public Task UploadFileAsync(string channelName, Stream fileStream, string fileName, string? size = null) Parameters channelName string fileStream Stream fileName string size string Returns Task" + "summary": "Class ApiClient Namespace EchoHub.Client.Services Assembly EchoHub.Client.dll public sealed class ApiClient : IDisposable Inheritance object ApiClient Implements IDisposable Inherited Members object.GetType() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors ApiClient(string) public ApiClient(string baseUrl) Parameters baseUrl string Properties BaseUrl public string BaseUrl { get; } Property Value string RefreshToken public string? RefreshToken { get; } Property Value string Token public string? Token { get; } Property Value string Methods AssignRoleAsync(string, ServerRole) public Task AssignRoleAsync(string username, ServerRole role) Parameters username string role ServerRole Returns Task BanUserAsync(string, string?) public Task BanUserAsync(string username, string? reason = null) Parameters username string reason string Returns Task CreateChannelAsync(string, string?, bool) public Task CreateChannelAsync(string name, string? topic = null, bool isPublic = true) Parameters name string topic string isPublic bool Returns Task DeleteChannelAsync(string) public Task DeleteChannelAsync(string channelName) Parameters channelName string Returns Task DeleteMessageAsync(Guid) public Task DeleteMessageAsync(Guid messageId) Parameters messageId Guid Returns Task Dispose() public void Dispose() GetChannelsAsync() public Task> GetChannelsAsync() Returns Task> GetEncryptionKeyAsync() public Task GetEncryptionKeyAsync() Returns Task GetServerInfoAsync() public Task GetServerInfoAsync() Returns Task GetUserProfileAsync(string) public Task GetUserProfileAsync(string username) Parameters username string Returns Task GetValidTokenAsync() Returns a valid access token, refreshing if expired. Used by EchoHubConnection for SignalR token provider. public Task GetValidTokenAsync() Returns Task KickUserAsync(string, string?) public Task KickUserAsync(string username, string? reason = null) Parameters username string reason string Returns Task LoginAsync(string, string) public Task LoginAsync(string username, string password) Parameters username string password string Returns Task LogoutAsync() public Task LogoutAsync() Returns Task MuteUserAsync(string, int?, string?) public Task MuteUserAsync(string username, int? durationMinutes = null, string? reason = null) Parameters username string durationMinutes int? reason string Returns Task NukeChannelAsync(string) public Task NukeChannelAsync(string channelName) Parameters channelName string Returns Task RefreshTokenAsync() public Task RefreshTokenAsync() Returns Task RegisterAsync(string, string, string?) public Task RegisterAsync(string username, string password, string? displayName = null) Parameters username string password string displayName string Returns Task SendUrlAsync(string, string, string?) public Task SendUrlAsync(string channelName, string url, string? size = null) Parameters channelName string url string size string Returns Task UnbanUserAsync(string) public Task UnbanUserAsync(string username) Parameters username string Returns Task UnmuteUserAsync(string) public Task UnmuteUserAsync(string username) Parameters username string Returns Task UpdateChannelTopicAsync(string, string?) public Task UpdateChannelTopicAsync(string channelName, string? topic) Parameters channelName string topic string Returns Task UpdateProfileAsync(UpdateProfileRequest) public Task UpdateProfileAsync(UpdateProfileRequest request) Parameters request UpdateProfileRequest Returns Task UploadAvatarAsync(Stream, string) public Task UploadAvatarAsync(Stream imageStream, string fileName) Parameters imageStream Stream fileName string Returns Task UploadFileAsync(string, Stream, string, string?) public Task UploadFileAsync(string channelName, Stream fileStream, string fileName, string? size = null) Parameters channelName string fileStream Stream fileName string size string Returns Task" + }, + "api/client/EchoHub.Client.Services.ClientEncryptionService.html": { + "href": "api/client/EchoHub.Client.Services.ClientEncryptionService.html", + "title": "Class ClientEncryptionService | EchoHub Documentation", + "summary": "Class ClientEncryptionService Namespace EchoHub.Client.Services Assembly EchoHub.Client.dll Client-side encryption service. Uses the same AES-256-GCM format as the server so messages are encrypted end-to-end between client and server. public sealed class ClientEncryptionService : IMessageEncryptionService Inheritance object ClientEncryptionService Implements IMessageEncryptionService Inherited Members object.GetType() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors ClientEncryptionService() public ClientEncryptionService() Properties EncryptDatabaseEnabled Whether database content should be encrypted at rest (server setting). public bool EncryptDatabaseEnabled { get; } Property Value bool IsInitialized public bool IsInitialized { get; } Property Value bool Methods Decrypt(string) public string Decrypt(string content) Parameters content string Returns string DecryptNullable(string?) public string? DecryptNullable(string? value) Parameters value string Returns string Encrypt(string) public string Encrypt(string plaintext) Parameters plaintext string Returns string EncryptNullable(string?) public string? EncryptNullable(string? value) Parameters value string Returns string SetKey(string) Initialize with the server's encryption key (fetched after login). public void SetKey(string base64Key) Parameters base64Key string" }, "api/client/EchoHub.Client.Services.EchoHubConnection.html": { "href": "api/client/EchoHub.Client.Services.EchoHubConnection.html", "title": "Class EchoHubConnection | EchoHub Documentation", - "summary": "Class EchoHubConnection Namespace EchoHub.Client.Services Assembly EchoHub.Client.dll public sealed class EchoHubConnection : IAsyncDisposable Inheritance object EchoHubConnection Implements IAsyncDisposable Inherited Members object.GetType() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors EchoHubConnection(string, ApiClient) public EchoHubConnection(string serverUrl, ApiClient apiClient) Parameters serverUrl string apiClient ApiClient Properties IsConnected public bool IsConnected { get; } Property Value bool Methods ConnectAsync() public Task ConnectAsync() Returns Task DisconnectAsync() public Task DisconnectAsync() Returns Task DisposeAsync() public ValueTask DisposeAsync() Returns ValueTask GetHistoryAsync(string, int) public Task> GetHistoryAsync(string channelName, int count = 100) Parameters channelName string count int Returns Task> GetOnlineUsersAsync(string) public Task> GetOnlineUsersAsync(string channelName) Parameters channelName string Returns Task> JoinChannelAsync(string) public Task> JoinChannelAsync(string channelName) Parameters channelName string Returns Task> LeaveChannelAsync(string) public Task LeaveChannelAsync(string channelName) Parameters channelName string Returns Task SendMessageAsync(string, string) public Task SendMessageAsync(string channelName, string content) Parameters channelName string content string Returns Task UpdateStatusAsync(UserStatus, string?) public Task UpdateStatusAsync(UserStatus status, string? statusMessage = null) Parameters status UserStatus statusMessage string Returns Task Events OnChannelNuked public event Action? OnChannelNuked Event Type Action OnChannelUpdated public event Action? OnChannelUpdated Event Type Action OnConnectionStateChanged public event Action? OnConnectionStateChanged Event Type Action OnError public event Action? OnError Event Type Action OnForceDisconnect public event Action? OnForceDisconnect Event Type Action OnMessageDeleted public event Action? OnMessageDeleted Event Type Action OnMessageReceived public event Action? OnMessageReceived Event Type Action OnReconnected public event Action? OnReconnected Event Type Action OnUserBanned public event Action? OnUserBanned Event Type Action OnUserJoined public event Action? OnUserJoined Event Type Action OnUserKicked public event Action? OnUserKicked Event Type Action OnUserLeft public event Action? OnUserLeft Event Type Action OnUserStatusChanged public event Action? OnUserStatusChanged Event Type Action" + "summary": "Class EchoHubConnection Namespace EchoHub.Client.Services Assembly EchoHub.Client.dll public sealed class EchoHubConnection : IAsyncDisposable Inheritance object EchoHubConnection Implements IAsyncDisposable Inherited Members object.GetType() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors EchoHubConnection(string, ApiClient, ClientEncryptionService) public EchoHubConnection(string serverUrl, ApiClient apiClient, ClientEncryptionService encryption) Parameters serverUrl string apiClient ApiClient encryption ClientEncryptionService Properties IsConnected public bool IsConnected { get; } Property Value bool Methods ConnectAsync() public Task ConnectAsync() Returns Task DisconnectAsync() public Task DisconnectAsync() Returns Task DisposeAsync() public ValueTask DisposeAsync() Returns ValueTask GetHistoryAsync(string, int) public Task> GetHistoryAsync(string channelName, int count = 100) Parameters channelName string count int Returns Task> GetOnlineUsersAsync(string) public Task> GetOnlineUsersAsync(string channelName) Parameters channelName string Returns Task> JoinChannelAsync(string) public Task> JoinChannelAsync(string channelName) Parameters channelName string Returns Task> LeaveChannelAsync(string) public Task LeaveChannelAsync(string channelName) Parameters channelName string Returns Task SendMessageAsync(string, string) public Task SendMessageAsync(string channelName, string content) Parameters channelName string content string Returns Task UpdateStatusAsync(UserStatus, string?) public Task UpdateStatusAsync(UserStatus status, string? statusMessage = null) Parameters status UserStatus statusMessage string Returns Task Events OnChannelNuked public event Action? OnChannelNuked Event Type Action OnChannelUpdated public event Action? OnChannelUpdated Event Type Action OnConnectionStateChanged public event Action? OnConnectionStateChanged Event Type Action OnError public event Action? OnError Event Type Action OnForceDisconnect public event Action? OnForceDisconnect Event Type Action OnMessageDeleted public event Action? OnMessageDeleted Event Type Action OnMessageReceived public event Action? OnMessageReceived Event Type Action OnReconnected public event Action? OnReconnected Event Type Action OnUserBanned public event Action? OnUserBanned Event Type Action OnUserJoined public event Action? OnUserJoined Event Type Action OnUserKicked public event Action? OnUserKicked Event Type Action OnUserLeft public event Action? OnUserLeft Event Type Action OnUserStatusChanged public event Action? OnUserStatusChanged Event Type Action" }, "api/client/EchoHub.Client.Services.NotificationSoundService.html": { "href": "api/client/EchoHub.Client.Services.NotificationSoundService.html", @@ -82,7 +87,7 @@ "api/client/EchoHub.Client.Services.html": { "href": "api/client/EchoHub.Client.Services.html", "title": "Namespace EchoHub.Client.Services | EchoHub Documentation", - "summary": "Namespace EchoHub.Client.Services Classes ApiClient EchoHubConnection NotificationSoundService UpdateChecker" + "summary": "Namespace EchoHub.Client.Services Classes ApiClient ClientEncryptionService Client-side encryption service. Uses the same AES-256-GCM format as the server so messages are encrypted end-to-end between client and server. EchoHubConnection NotificationSoundService UpdateChecker" }, "api/client/EchoHub.Client.Themes.Theme.html": { "href": "api/client/EchoHub.Client.Themes.Theme.html", @@ -249,10 +254,15 @@ "title": "Interface IEchoHubClient | EchoHub Documentation", "summary": "Interface IEchoHubClient Namespace EchoHub.Core.Contracts Assembly EchoHub.Core.dll Methods the server can invoke on connected clients. public interface IEchoHubClient Methods ChannelNuked(string) Task ChannelNuked(string channelName) Parameters channelName string Returns Task ChannelUpdated(ChannelDto) Task ChannelUpdated(ChannelDto channel) Parameters channel ChannelDto Returns Task Error(string) Task Error(string message) Parameters message string Returns Task ForceDisconnect(string) Task ForceDisconnect(string reason) Parameters reason string Returns Task MessageDeleted(string, Guid) Task MessageDeleted(string channelName, Guid messageId) Parameters channelName string messageId Guid Returns Task ReceiveMessage(MessageDto) Task ReceiveMessage(MessageDto message) Parameters message MessageDto Returns Task UserBanned(string, string?) Task UserBanned(string username, string? reason) Parameters username string reason string Returns Task UserJoined(string, string) Task UserJoined(string channelName, string username) Parameters channelName string username string Returns Task UserKicked(string, string, string?) Task UserKicked(string channelName, string username, string? reason) Parameters channelName string username string reason string Returns Task UserLeft(string, string) Task UserLeft(string channelName, string username) Parameters channelName string username string Returns Task UserStatusChanged(UserPresenceDto) Task UserStatusChanged(UserPresenceDto presence) Parameters presence UserPresenceDto Returns Task" }, + "api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html": { + "href": "api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html", + "title": "Interface IMessageEncryptionService | EchoHub Documentation", + "summary": "Interface IMessageEncryptionService Namespace EchoHub.Core.Contracts Assembly EchoHub.Core.dll public interface IMessageEncryptionService Properties EncryptDatabaseEnabled Whether database content should be encrypted at rest (server setting). bool EncryptDatabaseEnabled { get; } Property Value bool Methods Decrypt(string) string Decrypt(string content) Parameters content string Returns string DecryptNullable(string?) string? DecryptNullable(string? value) Parameters value string Returns string Encrypt(string) string Encrypt(string plaintext) Parameters plaintext string Returns string EncryptNullable(string?) string? EncryptNullable(string? value) Parameters value string Returns string" + }, "api/core/EchoHub.Core.Contracts.html": { "href": "api/core/EchoHub.Core.Contracts.html", "title": "Namespace EchoHub.Core.Contracts | EchoHub Documentation", - "summary": "Namespace EchoHub.Core.Contracts Classes ChannelListItem Interfaces IChatBroadcaster IChatService IEchoHubClient Methods the server can invoke on connected clients." + "summary": "Namespace EchoHub.Core.Contracts Classes ChannelListItem Interfaces IChatBroadcaster IChatService IEchoHubClient Methods the server can invoke on connected clients. IMessageEncryptionService" }, "api/core/EchoHub.Core.DTOs.AssignRoleRequest.html": { "href": "api/core/EchoHub.Core.DTOs.AssignRoleRequest.html", @@ -284,6 +294,11 @@ "title": "Class EmbedDto | EchoHub Documentation", "summary": "Class EmbedDto Namespace EchoHub.Core.DTOs Assembly EchoHub.Core.dll public record EmbedDto : IEquatable Inheritance object EmbedDto Implements IEquatable Inherited Members object.GetType() object.MemberwiseClone() object.Equals(object, object) object.ReferenceEquals(object, object) Constructors EmbedDto(EmbedDto) protected EmbedDto(EmbedDto original) Parameters original EmbedDto EmbedDto(string?, string?, string?, string?, string) public EmbedDto(string? SiteName, string? Title, string? Description, string? ImageAscii, string Url) Parameters SiteName string Title string Description string ImageAscii string Url string Properties Description public string? Description { get; init; } Property Value string EqualityContract protected virtual Type EqualityContract { get; } Property Value Type ImageAscii public string? ImageAscii { get; init; } Property Value string SiteName public string? SiteName { get; init; } Property Value string Title public string? Title { get; init; } Property Value string Url public string Url { get; init; } Property Value string Methods Deconstruct(out string?, out string?, out string?, out string?, out string) public void Deconstruct(out string? SiteName, out string? Title, out string? Description, out string? ImageAscii, out string Url) Parameters SiteName string Title string Description string ImageAscii string Url string Equals(EmbedDto?) public virtual bool Equals(EmbedDto? other) Parameters other EmbedDto Returns bool Equals(object?) public override bool Equals(object? obj) Parameters obj object Returns bool GetHashCode() public override int GetHashCode() Returns int PrintMembers(StringBuilder) protected virtual bool PrintMembers(StringBuilder builder) Parameters builder StringBuilder Returns bool ToString() public override string ToString() Returns string Operators operator ==(EmbedDto?, EmbedDto?) public static bool operator ==(EmbedDto? left, EmbedDto? right) Parameters left EmbedDto right EmbedDto Returns bool operator !=(EmbedDto?, EmbedDto?) public static bool operator !=(EmbedDto? left, EmbedDto? right) Parameters left EmbedDto right EmbedDto Returns bool" }, + "api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html": { + "href": "api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html", + "title": "Class EncryptionKeyResponse | EchoHub Documentation", + "summary": "Class EncryptionKeyResponse Namespace EchoHub.Core.DTOs Assembly EchoHub.Core.dll public record EncryptionKeyResponse : IEquatable Inheritance object EncryptionKeyResponse Implements IEquatable Inherited Members object.GetType() object.MemberwiseClone() object.Equals(object, object) object.ReferenceEquals(object, object) Constructors EncryptionKeyResponse(EncryptionKeyResponse) protected EncryptionKeyResponse(EncryptionKeyResponse original) Parameters original EncryptionKeyResponse EncryptionKeyResponse(string) public EncryptionKeyResponse(string Key) Parameters Key string Properties EqualityContract protected virtual Type EqualityContract { get; } Property Value Type Key public string Key { get; init; } Property Value string Methods Deconstruct(out string) public void Deconstruct(out string Key) Parameters Key string Equals(EncryptionKeyResponse?) public virtual bool Equals(EncryptionKeyResponse? other) Parameters other EncryptionKeyResponse Returns bool Equals(object?) public override bool Equals(object? obj) Parameters obj object Returns bool GetHashCode() public override int GetHashCode() Returns int PrintMembers(StringBuilder) protected virtual bool PrintMembers(StringBuilder builder) Parameters builder StringBuilder Returns bool ToString() public override string ToString() Returns string Operators operator ==(EncryptionKeyResponse?, EncryptionKeyResponse?) public static bool operator ==(EncryptionKeyResponse? left, EncryptionKeyResponse? right) Parameters left EncryptionKeyResponse right EncryptionKeyResponse Returns bool operator !=(EncryptionKeyResponse?, EncryptionKeyResponse?) public static bool operator !=(EncryptionKeyResponse? left, EncryptionKeyResponse? right) Parameters left EncryptionKeyResponse right EncryptionKeyResponse Returns bool" + }, "api/core/EchoHub.Core.DTOs.ErrorResponse.html": { "href": "api/core/EchoHub.Core.DTOs.ErrorResponse.html", "title": "Class ErrorResponse | EchoHub Documentation", @@ -377,7 +392,7 @@ "api/core/EchoHub.Core.DTOs.html": { "href": "api/core/EchoHub.Core.DTOs.html", "title": "Namespace EchoHub.Core.DTOs | EchoHub Documentation", - "summary": "Namespace EchoHub.Core.DTOs Classes AssignRoleRequest AvatarUploadResponse BanRequest ChannelDto CreateChannelRequest EmbedDto ErrorResponse KickRequest LoginRequest LoginResponse MessageDto MuteRequest PaginatedResponse RefreshRequest RegisterRequest SendMessageRequest SendUrlRequest ServerStatusDto UpdateProfileRequest UpdateStatusRequest UpdateTopicRequest UserDto UserPresenceDto UserProfileDto" + "summary": "Namespace EchoHub.Core.DTOs Classes AssignRoleRequest AvatarUploadResponse BanRequest ChannelDto CreateChannelRequest EmbedDto EncryptionKeyResponse ErrorResponse KickRequest LoginRequest LoginResponse MessageDto MuteRequest PaginatedResponse RefreshRequest RegisterRequest SendMessageRequest SendUrlRequest ServerStatusDto UpdateProfileRequest UpdateStatusRequest UpdateTopicRequest UserDto UserPresenceDto UserProfileDto" }, "api/core/EchoHub.Core.Models.Channel.html": { "href": "api/core/EchoHub.Core.Models.Channel.html", @@ -437,7 +452,7 @@ "api/server-irc/EchoHub.Server.Irc.IrcBroadcaster.html": { "href": "api/server-irc/EchoHub.Server.Irc.IrcBroadcaster.html", "title": "Class IrcBroadcaster | EchoHub Documentation", - "summary": "Class IrcBroadcaster Namespace EchoHub.Server.Irc Assembly EchoHub.Server.Irc.dll public class IrcBroadcaster : IChatBroadcaster Inheritance object IrcBroadcaster Implements IChatBroadcaster Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors IrcBroadcaster(IrcGatewayService) public IrcBroadcaster(IrcGatewayService gateway) Parameters gateway IrcGatewayService Methods ForceDisconnectUserAsync(List, string) public Task ForceDisconnectUserAsync(List connectionIds, string reason) Parameters connectionIds List reason string Returns Task SendChannelNukedAsync(string) public Task SendChannelNukedAsync(string channelName) Parameters channelName string Returns Task SendChannelUpdatedAsync(ChannelDto, string?) public Task SendChannelUpdatedAsync(ChannelDto channel, string? channelName = null) Parameters channel ChannelDto channelName string Returns Task SendErrorAsync(string, string) public Task SendErrorAsync(string connectionId, string message) Parameters connectionId string message string Returns Task SendMessageDeletedAsync(string, Guid) public Task SendMessageDeletedAsync(string channelName, Guid messageId) Parameters channelName string messageId Guid Returns Task SendMessageToChannelAsync(string, MessageDto) public Task SendMessageToChannelAsync(string channelName, MessageDto message) Parameters channelName string message MessageDto Returns Task SendUserBannedAsync(string, string?) public Task SendUserBannedAsync(string username, string? reason) Parameters username string reason string Returns Task SendUserJoinedAsync(string, string, string?) public Task SendUserJoinedAsync(string channelName, string username, string? excludeConnectionId = null) Parameters channelName string username string excludeConnectionId string Returns Task SendUserKickedAsync(string, string, string?) public Task SendUserKickedAsync(string channelName, string username, string? reason) Parameters channelName string username string reason string Returns Task SendUserLeftAsync(string, string) public Task SendUserLeftAsync(string channelName, string username) Parameters channelName string username string Returns Task SendUserStatusChangedAsync(List, UserPresenceDto) public Task SendUserStatusChangedAsync(List channelNames, UserPresenceDto presence) Parameters channelNames List presence UserPresenceDto Returns Task" + "summary": "Class IrcBroadcaster Namespace EchoHub.Server.Irc Assembly EchoHub.Server.Irc.dll public class IrcBroadcaster : IChatBroadcaster Inheritance object IrcBroadcaster Implements IChatBroadcaster Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors IrcBroadcaster(IrcGatewayService, IMessageEncryptionService) public IrcBroadcaster(IrcGatewayService gateway, IMessageEncryptionService encryption) Parameters gateway IrcGatewayService encryption IMessageEncryptionService Methods ForceDisconnectUserAsync(List, string) public Task ForceDisconnectUserAsync(List connectionIds, string reason) Parameters connectionIds List reason string Returns Task SendChannelNukedAsync(string) public Task SendChannelNukedAsync(string channelName) Parameters channelName string Returns Task SendChannelUpdatedAsync(ChannelDto, string?) public Task SendChannelUpdatedAsync(ChannelDto channel, string? channelName = null) Parameters channel ChannelDto channelName string Returns Task SendErrorAsync(string, string) public Task SendErrorAsync(string connectionId, string message) Parameters connectionId string message string Returns Task SendMessageDeletedAsync(string, Guid) public Task SendMessageDeletedAsync(string channelName, Guid messageId) Parameters channelName string messageId Guid Returns Task SendMessageToChannelAsync(string, MessageDto) public Task SendMessageToChannelAsync(string channelName, MessageDto message) Parameters channelName string message MessageDto Returns Task SendUserBannedAsync(string, string?) public Task SendUserBannedAsync(string username, string? reason) Parameters username string reason string Returns Task SendUserJoinedAsync(string, string, string?) public Task SendUserJoinedAsync(string channelName, string username, string? excludeConnectionId = null) Parameters channelName string username string excludeConnectionId string Returns Task SendUserKickedAsync(string, string, string?) public Task SendUserKickedAsync(string channelName, string username, string? reason) Parameters channelName string username string reason string Returns Task SendUserLeftAsync(string, string) public Task SendUserLeftAsync(string channelName, string username) Parameters channelName string username string Returns Task SendUserStatusChangedAsync(List, UserPresenceDto) public Task SendUserStatusChangedAsync(List channelNames, UserPresenceDto presence) Parameters channelNames List presence UserPresenceDto Returns Task" }, "api/server-irc/EchoHub.Server.Irc.IrcClientConnection.html": { "href": "api/server-irc/EchoHub.Server.Irc.IrcClientConnection.html", @@ -502,7 +517,7 @@ "api/server/EchoHub.Server.Controllers.ChannelsController.html": { "href": "api/server/EchoHub.Server.Controllers.ChannelsController.html", "title": "Class ChannelsController | EchoHub Documentation", - "summary": "Class ChannelsController Namespace EchoHub.Server.Controllers Assembly EchoHub.Server.dll [ApiController] [Route(\"api/channels\")] [Authorize] [EnableRateLimiting(\"general\")] public class ChannelsController : ControllerBase Inheritance object ControllerBase ChannelsController Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors ChannelsController(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService) public ChannelsController(EchoHubDbContext db, FileStorageService fileStorage, ImageToAsciiService asciiService, IHttpClientFactory httpClientFactory, IChatService chatService) Parameters db EchoHubDbContext fileStorage FileStorageService asciiService ImageToAsciiService httpClientFactory IHttpClientFactory chatService IChatService Methods CreateChannel(CreateChannelRequest) [HttpPost] public Task CreateChannel(CreateChannelRequest request) Parameters request CreateChannelRequest Returns Task DeleteChannel(string) [HttpDelete(\"{channel}\")] public Task DeleteChannel(string channel) Parameters channel string Returns Task GetChannels(int, int) [HttpGet] public Task GetChannels(int offset = 0, int limit = 50) Parameters offset int limit int Returns Task SendUrl(string, SendUrlRequest, string?) [HttpPost(\"{channel}/send-url\")] [EnableRateLimiting(\"upload\")] public Task SendUrl(string channel, SendUrlRequest request, string? size = null) Parameters channel string request SendUrlRequest size string Returns Task UpdateTopic(string, UpdateTopicRequest) [HttpPut(\"{channel}/topic\")] public Task UpdateTopic(string channel, UpdateTopicRequest request) Parameters channel string request UpdateTopicRequest Returns Task Upload(string, string?) [HttpPost(\"{channel}/upload\")] [EnableRateLimiting(\"upload\")] public Task Upload(string channel, string? size = null) Parameters channel string size string Returns Task" + "summary": "Class ChannelsController Namespace EchoHub.Server.Controllers Assembly EchoHub.Server.dll [ApiController] [Route(\"api/channels\")] [Authorize] [EnableRateLimiting(\"general\")] public class ChannelsController : ControllerBase Inheritance object ControllerBase ChannelsController Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors ChannelsController(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService, IMessageEncryptionService) public ChannelsController(EchoHubDbContext db, FileStorageService fileStorage, ImageToAsciiService asciiService, IHttpClientFactory httpClientFactory, IChatService chatService, IMessageEncryptionService encryption) Parameters db EchoHubDbContext fileStorage FileStorageService asciiService ImageToAsciiService httpClientFactory IHttpClientFactory chatService IChatService encryption IMessageEncryptionService Methods CreateChannel(CreateChannelRequest) [HttpPost] public Task CreateChannel(CreateChannelRequest request) Parameters request CreateChannelRequest Returns Task DeleteChannel(string) [HttpDelete(\"{channel}\")] public Task DeleteChannel(string channel) Parameters channel string Returns Task GetChannels(int, int) [HttpGet] public Task GetChannels(int offset = 0, int limit = 50) Parameters offset int limit int Returns Task SendUrl(string, SendUrlRequest, string?) [HttpPost(\"{channel}/send-url\")] [EnableRateLimiting(\"upload\")] public Task SendUrl(string channel, SendUrlRequest request, string? size = null) Parameters channel string request SendUrlRequest size string Returns Task UpdateTopic(string, UpdateTopicRequest) [HttpPut(\"{channel}/topic\")] public Task UpdateTopic(string channel, UpdateTopicRequest request) Parameters channel string request UpdateTopicRequest Returns Task Upload(string, string?) [HttpPost(\"{channel}/upload\")] [EnableRateLimiting(\"upload\")] public Task Upload(string channel, string? size = null) Parameters channel string size string Returns Task" }, "api/server/EchoHub.Server.Controllers.FilesController.html": { "href": "api/server/EchoHub.Server.Controllers.FilesController.html", @@ -517,7 +532,7 @@ "api/server/EchoHub.Server.Controllers.ServerController.html": { "href": "api/server/EchoHub.Server.Controllers.ServerController.html", "title": "Class ServerController | EchoHub Documentation", - "summary": "Class ServerController Namespace EchoHub.Server.Controllers Assembly EchoHub.Server.dll [ApiController] [Route(\"api/server\")] public class ServerController : ControllerBase Inheritance object ControllerBase ServerController Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors ServerController(EchoHubDbContext, IConfiguration) public ServerController(EchoHubDbContext db, IConfiguration config) Parameters db EchoHubDbContext config IConfiguration Methods GetInfo() [HttpGet(\"info\")] public Task GetInfo() Returns Task" + "summary": "Class ServerController Namespace EchoHub.Server.Controllers Assembly EchoHub.Server.dll [ApiController] [Route(\"api/server\")] public class ServerController : ControllerBase Inheritance object ControllerBase ServerController Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors ServerController(EchoHubDbContext, IConfiguration) public ServerController(EchoHubDbContext db, IConfiguration config) Parameters db EchoHubDbContext config IConfiguration Methods GetEncryptionKey() [HttpGet(\"encryption-key\")] [Authorize] [EnableRateLimiting(\"auth\")] public IActionResult GetEncryptionKey() Returns IActionResult GetInfo() [HttpGet(\"info\")] public Task GetInfo() Returns Task" }, "api/server/EchoHub.Server.Controllers.UsersController.html": { "href": "api/server/EchoHub.Server.Controllers.UsersController.html", @@ -544,6 +559,11 @@ "title": "Class AddChannelMembership | EchoHub Documentation", "summary": "Class AddChannelMembership Namespace EchoHub.Server.Data.Migrations Assembly EchoHub.Server.dll [DbContext(typeof(EchoHubDbContext))] [Migration(\"20260219181720_AddChannelMembership\")] public class AddChannelMembership : Migration Inheritance object Migration AddChannelMembership Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors AddChannelMembership() public AddChannelMembership() Methods BuildTargetModel(ModelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder) Parameters modelBuilder ModelBuilder Down(MigrationBuilder) protected override void Down(MigrationBuilder migrationBuilder) Parameters migrationBuilder MigrationBuilder Up(MigrationBuilder) protected override void Up(MigrationBuilder migrationBuilder) Parameters migrationBuilder MigrationBuilder" }, + "api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html": { + "href": "api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html", + "title": "Class AddEncryptionSupport | EchoHub Documentation", + "summary": "Class AddEncryptionSupport Namespace EchoHub.Server.Data.Migrations Assembly EchoHub.Server.dll [DbContext(typeof(EchoHubDbContext))] [Migration(\"20260220133627_AddEncryptionSupport\")] public class AddEncryptionSupport : Migration Inheritance object Migration AddEncryptionSupport Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors AddEncryptionSupport() public AddEncryptionSupport() Methods BuildTargetModel(ModelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder) Parameters modelBuilder ModelBuilder Down(MigrationBuilder) protected override void Down(MigrationBuilder migrationBuilder) Parameters migrationBuilder MigrationBuilder Up(MigrationBuilder) protected override void Up(MigrationBuilder migrationBuilder) Parameters migrationBuilder MigrationBuilder" + }, "api/server/EchoHub.Server.Data.Migrations.AddMessageEmbed.html": { "href": "api/server/EchoHub.Server.Data.Migrations.AddMessageEmbed.html", "title": "Class AddMessageEmbed | EchoHub Documentation", @@ -562,7 +582,7 @@ "api/server/EchoHub.Server.Data.Migrations.html": { "href": "api/server/EchoHub.Server.Data.Migrations.html", "title": "Namespace EchoHub.Server.Data.Migrations | EchoHub Documentation", - "summary": "Namespace EchoHub.Server.Data.Migrations Classes AddChannelIsPublic AddChannelMembership AddMessageEmbed AddModerationRoles InitialCreate" + "summary": "Namespace EchoHub.Server.Data.Migrations Classes AddChannelIsPublic AddChannelMembership AddEncryptionSupport AddMessageEmbed AddModerationRoles InitialCreate" }, "api/server/EchoHub.Server.Data.html": { "href": "api/server/EchoHub.Server.Data.html", @@ -582,7 +602,7 @@ "api/server/EchoHub.Server.Services.ChatService.html": { "href": "api/server/EchoHub.Server.Services.ChatService.html", "title": "Class ChatService | EchoHub Documentation", - "summary": "Class ChatService Namespace EchoHub.Server.Services Assembly EchoHub.Server.dll public class ChatService : IChatService Inheritance object ChatService Implements IChatService Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors ChatService(IServiceScopeFactory, PresenceTracker, IEnumerable, LinkEmbedService, ILogger) public ChatService(IServiceScopeFactory scopeFactory, PresenceTracker presenceTracker, IEnumerable broadcasters, LinkEmbedService embedService, ILogger logger) Parameters scopeFactory IServiceScopeFactory presenceTracker PresenceTracker broadcasters IEnumerable embedService LinkEmbedService logger ILogger Methods AuthenticateUserAsync(string, string) public Task<(Guid UserId, string Username)?> AuthenticateUserAsync(string username, string password) Parameters username string password string Returns Task<(Guid UserId, string Username)?> BroadcastChannelUpdatedAsync(ChannelDto, string?) public Task BroadcastChannelUpdatedAsync(ChannelDto channel, string? channelName = null) Parameters channel ChannelDto channelName string Returns Task BroadcastMessageAsync(string, MessageDto) public Task BroadcastMessageAsync(string channelName, MessageDto message) Parameters channelName string message MessageDto Returns Task GetChannelHistoryAsync(string, int) public Task> GetChannelHistoryAsync(string channelName, int count) Parameters channelName string count int Returns Task> GetChannelListAsync() public Task> GetChannelListAsync() Returns Task> GetChannelTopicAsync(string) public Task<(string? Topic, bool Exists)> GetChannelTopicAsync(string channelName) Parameters channelName string Returns Task<(string Topic, bool Exists)> GetChannelsForUserAsync(string) public Task> GetChannelsForUserAsync(string username) Parameters username string Returns Task> GetOnlineUsersAsync(string) public Task> GetOnlineUsersAsync(string channelName) Parameters channelName string Returns Task> GetUserProfileAsync(string) public Task GetUserProfileAsync(string username) Parameters username string Returns Task JoinChannelAsync(string, Guid, string, string) public Task<(List History, string? Error)> JoinChannelAsync(string connectionId, Guid userId, string username, string channelName) Parameters connectionId string userId Guid username string channelName string Returns Task<(List History, string Error)> LeaveChannelAsync(string, string, string) public Task LeaveChannelAsync(string connectionId, string username, string channelName) Parameters connectionId string username string channelName string Returns Task SendMessageAsync(Guid, string, string, string) public Task SendMessageAsync(Guid userId, string username, string channelName, string content) Parameters userId Guid username string channelName string content string Returns Task UpdateStatusAsync(Guid, string, UserStatus, string?) public Task UpdateStatusAsync(Guid userId, string username, UserStatus status, string? statusMessage) Parameters userId Guid username string status UserStatus statusMessage string Returns Task UserConnectedAsync(string, Guid, string) public Task UserConnectedAsync(string connectionId, Guid userId, string username) Parameters connectionId string userId Guid username string Returns Task UserDisconnectedAsync(string) public Task UserDisconnectedAsync(string connectionId) Parameters connectionId string Returns Task" + "summary": "Class ChatService Namespace EchoHub.Server.Services Assembly EchoHub.Server.dll public class ChatService : IChatService Inheritance object ChatService Implements IChatService Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors ChatService(IServiceScopeFactory, PresenceTracker, IEnumerable, LinkEmbedService, IMessageEncryptionService, ILogger) public ChatService(IServiceScopeFactory scopeFactory, PresenceTracker presenceTracker, IEnumerable broadcasters, LinkEmbedService embedService, IMessageEncryptionService encryption, ILogger logger) Parameters scopeFactory IServiceScopeFactory presenceTracker PresenceTracker broadcasters IEnumerable embedService LinkEmbedService encryption IMessageEncryptionService logger ILogger Methods AuthenticateUserAsync(string, string) public Task<(Guid UserId, string Username)?> AuthenticateUserAsync(string username, string password) Parameters username string password string Returns Task<(Guid UserId, string Username)?> BroadcastChannelUpdatedAsync(ChannelDto, string?) public Task BroadcastChannelUpdatedAsync(ChannelDto channel, string? channelName = null) Parameters channel ChannelDto channelName string Returns Task BroadcastMessageAsync(string, MessageDto) public Task BroadcastMessageAsync(string channelName, MessageDto message) Parameters channelName string message MessageDto Returns Task GetChannelHistoryAsync(string, int) public Task> GetChannelHistoryAsync(string channelName, int count) Parameters channelName string count int Returns Task> GetChannelListAsync() public Task> GetChannelListAsync() Returns Task> GetChannelTopicAsync(string) public Task<(string? Topic, bool Exists)> GetChannelTopicAsync(string channelName) Parameters channelName string Returns Task<(string Topic, bool Exists)> GetChannelsForUserAsync(string) public Task> GetChannelsForUserAsync(string username) Parameters username string Returns Task> GetOnlineUsersAsync(string) public Task> GetOnlineUsersAsync(string channelName) Parameters channelName string Returns Task> GetUserProfileAsync(string) public Task GetUserProfileAsync(string username) Parameters username string Returns Task JoinChannelAsync(string, Guid, string, string) public Task<(List History, string? Error)> JoinChannelAsync(string connectionId, Guid userId, string username, string channelName) Parameters connectionId string userId Guid username string channelName string Returns Task<(List History, string Error)> LeaveChannelAsync(string, string, string) public Task LeaveChannelAsync(string connectionId, string username, string channelName) Parameters connectionId string username string channelName string Returns Task SendMessageAsync(Guid, string, string, string) public Task SendMessageAsync(Guid userId, string username, string channelName, string content) Parameters userId Guid username string channelName string content string Returns Task UpdateStatusAsync(Guid, string, UserStatus, string?) public Task UpdateStatusAsync(Guid userId, string username, UserStatus status, string? statusMessage) Parameters userId Guid username string status UserStatus statusMessage string Returns Task UserConnectedAsync(string, Guid, string) public Task UserConnectedAsync(string connectionId, Guid userId, string username) Parameters connectionId string userId Guid username string Returns Task UserDisconnectedAsync(string) public Task UserDisconnectedAsync(string connectionId) Parameters connectionId string Returns Task" }, "api/server/EchoHub.Server.Services.FileStorageService.html": { "href": "api/server/EchoHub.Server.Services.FileStorageService.html", @@ -604,6 +624,11 @@ "title": "Class LinkEmbedService | EchoHub Documentation", "summary": "Class LinkEmbedService Namespace EchoHub.Server.Services Assembly EchoHub.Server.dll public class LinkEmbedService Inheritance object LinkEmbedService Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors LinkEmbedService(IHttpClientFactory, ILogger) public LinkEmbedService(IHttpClientFactory httpClientFactory, ILogger logger) Parameters httpClientFactory IHttpClientFactory logger ILogger Methods TryGetEmbedsAsync(string) Detect all URLs in message content and attempt to fetch OG embed data for each. Returns null if no URLs found or all fetches fail. Never throws — all errors are caught internally. public Task?> TryGetEmbedsAsync(string content) Parameters content string Returns Task>" }, + "api/server/EchoHub.Server.Services.MessageEncryptionService.html": { + "href": "api/server/EchoHub.Server.Services.MessageEncryptionService.html", + "title": "Class MessageEncryptionService | EchoHub Documentation", + "summary": "Class MessageEncryptionService Namespace EchoHub.Server.Services Assembly EchoHub.Server.dll public class MessageEncryptionService : IMessageEncryptionService Inheritance object MessageEncryptionService Implements IMessageEncryptionService Inherited Members object.GetType() object.MemberwiseClone() object.ToString() object.Equals(object) object.Equals(object, object) object.ReferenceEquals(object, object) object.GetHashCode() Constructors MessageEncryptionService(IConfiguration, ILogger) public MessageEncryptionService(IConfiguration configuration, ILogger logger) Parameters configuration IConfiguration logger ILogger Properties EncryptDatabaseEnabled Whether database content should be encrypted at rest (server setting). public bool EncryptDatabaseEnabled { get; } Property Value bool Methods Decrypt(string) public string Decrypt(string content) Parameters content string Returns string DecryptNullable(string?) public string? DecryptNullable(string? value) Parameters value string Returns string Encrypt(string) public string Encrypt(string plaintext) Parameters plaintext string Returns string EncryptNullable(string?) public string? EncryptNullable(string? value) Parameters value string Returns string" + }, "api/server/EchoHub.Server.Services.PresenceTracker.html": { "href": "api/server/EchoHub.Server.Services.PresenceTracker.html", "title": "Class PresenceTracker | EchoHub Documentation", @@ -622,7 +647,7 @@ "api/server/EchoHub.Server.Services.html": { "href": "api/server/EchoHub.Server.Services.html", "title": "Namespace EchoHub.Server.Services | EchoHub Documentation", - "summary": "Namespace EchoHub.Server.Services Classes ChatService FileStorageService FileValidationHelper ImageToAsciiService LinkEmbedService PresenceTracker ServerDirectoryService SignalRBroadcaster" + "summary": "Namespace EchoHub.Server.Services Classes ChatService FileStorageService FileValidationHelper ImageToAsciiService LinkEmbedService MessageEncryptionService PresenceTracker ServerDirectoryService SignalRBroadcaster" }, "api/server/EchoHub.Server.Setup.DataMigrationService.html": { "href": "api/server/EchoHub.Server.Setup.DataMigrationService.html", @@ -649,6 +674,11 @@ "title": "Architecture | EchoHub Documentation", "summary": "Architecture Overview EchoHub follows a decentralized model where each server is fully independent. There is no central authority or account federation. Users create one account per server. The server exposes two protocol interfaces to the same chat backend: IRC Client ──► TCP :6667 ──► IrcGateway ──┐ ├──► ChatService ──► DB + PresenceTracker TUI Client ──► WebSocket ──► ChatHub ─────┘ Both protocols call into a shared IChatService for business logic. Events fan out to all registered IChatBroadcaster implementations (SignalR and IRC). Components EchoHub.Core Shared library containing: Models: User, Channel, Message, RefreshToken DTOs: Record types for API requests/responses Contracts: IChatService (protocol-agnostic chat operations), IChatBroadcaster (event fan-out interface), IEchoHubClient (SignalR client interface) Constants: ValidationConstants (shared regex patterns), HubConstants EchoHub.Server ASP.NET Core web application: Controllers: REST API endpoints for auth, channels, users, files, server info Hubs: SignalR ChatHub -- thin adapter delegating to IChatService Auth: JWT token service (15-min access tokens, 30-day refresh tokens) Data: EF Core with SQLite Services: ChatService (core business logic), SignalRBroadcaster, presence tracking, file storage, image-to-ASCII conversion EchoHub.Server.Irc IRC protocol gateway (separate project for clean separation of concerns): IrcGatewayService: BackgroundService with TCP listener on configured port(s), optional TLS IrcCommandHandler: Per-client IRC command dispatch -- handles CAP/SASL, NICK/USER/PASS, JOIN/PART/PRIVMSG/QUIT, NAMES/TOPIC/WHO/WHOIS/AWAY/LIST/MODE/MOTD IrcBroadcaster: IChatBroadcaster implementation that formats chat events as IRC protocol lines, with echo suppression (IRC convention) IrcMessageFormatter: Converts MessageDto to IRC PRIVMSG lines -- splits long text at word boundaries (~400 byte chunks), sends images as ASCII art line-by-line IRC users authenticate with existing EchoHub accounts via PASS/NICK/USER or SASL PLAIN (BCrypt verification against the database). EchoHub.Client Terminal.Gui v2 TUI application: UI: Main window, dialogs, chat renderer with ANSI color support Services: API client with automatic token refresh, SignalR connection wrapper Themes: 13 built-in color themes Config: Client configuration management Communication REST API for authentication, profile management, channel CRUD, file uploads SignalR WebSocket for real-time messaging and presence updates (TUI client) IRC TCP for real-time messaging via standard IRC protocol (IRC clients) JWT tokens passed via query string for SignalR authentication IRC authentication via PASS/SASL PLAIN against BCrypt password hashes Broadcaster Pattern The IChatBroadcaster interface allows multiple protocols to receive chat events: SignalRBroadcaster: Wraps IHubContext, filters out IRC connections IrcBroadcaster: Iterates live IRC connections in a channel, formats events as IRC protocol lines Both are registered in DI and called by ChatService when events occur. This means a message sent from an IRC client appears in the TUI client, and vice versa." }, + "articles/encryption.html": { + "href": "articles/encryption.html", + "title": "Message Encryption | EchoHub Documentation", + "summary": "Message Encryption EchoHub uses application-layer AES-256-GCM encryption to protect message content in transit between clients and the server. This is an additional layer on top of TLS, protecting against ISPs, proxies, and any middleman that can inspect HTTPS traffic (e.g. corporate proxies with trusted root CA certificates). How It Works sequenceDiagram participant Sender as TUI Client (Sender) participant Server participant Receiver as TUI Client (Receiver) participant IRC as IRC Client Sender->>Sender: encrypt(plaintext) Sender->>Server: $ENC$v1$... (SignalR) Server->>Server: decrypt → validate/sanitize Server->>Server: fetch embeds on plaintext Server->>Server: (optional) encrypt for DB storage Server->>Server: encrypt(plaintext) with fresh nonce Server->>Receiver: $ENC$v1$... (SignalR broadcast) Receiver->>Receiver: decrypt → display Server->>Server: decrypt for IRC Server->>IRC: plaintext (IRC PRIVMSG) Client encrypts the message before sending it over SignalR Server decrypts to validate content, sanitize newlines, and fetch link embeds Server re-encrypts with a fresh nonce and broadcasts to all connected SignalR clients Clients decrypt the broadcast and display the plaintext IRC clients receive plaintext automatically (the IRC broadcaster decrypts before forwarding) Each encryption uses a random 12-byte nonce, so the same message produces different ciphertext every time. Encryption Key A 256-bit AES key is auto-generated on first server startup and saved to appsettings.json: { \"Encryption\": { \"Key\": \"base64-encoded-32-byte-key\", \"EncryptDatabase\": false } } The key is generated by FirstRunSetup using RandomNumberGenerator.GetBytes(32). If the key is missing or empty when the server starts, a new one is created automatically. Clients fetch the key after login via an authenticated endpoint (GET /api/server/encryption-key). No manual configuration is needed on the client side. Encrypted Content Format Encrypted content uses a self-describing format: $ENC$v1${nonce_base64}${ciphertext+tag_base64} $ENC$v1$ — version prefix (allows future algorithm changes) Nonce — 12 bytes, Base64-encoded, randomly generated per message Ciphertext + Tag — AES-256-GCM output with 16-byte authentication tag appended The authentication tag ensures both confidentiality and integrity — any tampering with the ciphertext is detected during decryption. Database Encryption (Optional) By default, messages are stored as plaintext in the database. Transport encryption still protects everything on the wire, but the SQLite file itself contains readable messages. To encrypt messages at rest, enable the setting: { \"Encryption\": { \"Key\": \"...\", \"EncryptDatabase\": true } } Behavior by Setting Setting DB Storage Transport Key Rotation Risk false (default) Plaintext Encrypted None - stored data is unaffected true Encrypted Encrypted Changing the key makes old messages unreadable Mixed Content The server handles mixed encrypted/plaintext content in the database gracefully. When reading messages: Content starting with $ENC$v1$ is decrypted Everything else is treated as plaintext This means you can safely toggle EncryptDatabase at any time. Old messages remain readable regardless of the current setting. Enabling Encryption at Rest When you set EncryptDatabase: true, only new messages are encrypted going forward. Existing plaintext messages in the database are not retroactively encrypted. This is intentional — it keeps key rotation safe and avoids irreversible bulk changes. Key Rotation Changing the encryption key is safe: Plaintext messages — always readable regardless of key Messages encrypted with the old key — will show [encrypted message — decryption failed] New messages — encrypted with the new key going forward If you need to recover old encrypted messages, restore the original key from a backup of appsettings.json. Since plaintext messages are never retroactively encrypted, you'll never lose access to your entire history from a key change. Security Considerations What This Protects Against Passive network sniffing — messages are encrypted even if captured off the wire ISP/proxy inspection — content is encrypted at the application layer, independent of TLS Database theft (when EncryptDatabase: true) — SQLite file contains only ciphertext Limitations TLS-inspecting proxies — if a corporate proxy terminates TLS with a trusted root CA, it can intercept the key exchange (GET /api/server/encryption-key) and read all traffic. A future upgrade to ECDH key exchange would address this. Server has full access — the server decrypts all messages for processing. This is not end-to-end encryption between users; it's transport encryption between client and server. IRC clients receive plaintext — IRC is an open protocol and third-party clients cannot participate in the encryption scheme. Troubleshooting Messages show [encrypted message — decryption failed, try re-logging to fetch the latest key] The client's encryption key doesn't match the server's. This happens when: The server's encryption key was rotated while the client was connected The client cached a stale key Fix: Disconnect and reconnect (re-login). The client fetches the current key on each login. Messages show [encrypted message — decryption failed] in channel history The server cannot decrypt messages stored in the database. This happens when: EncryptDatabase was enabled, and the key was changed afterwards Fix: Restore the original key from a backup. There is no way to recover messages encrypted with a lost key." + }, "articles/getting-started.html": { "href": "articles/getting-started.html", "title": "Getting Started | EchoHub Documentation", @@ -694,6 +724,11 @@ "title": "v0.2.3 - Moderation, Embeds & UI Overhaul | EchoHub Documentation", "summary": "v0.2.3 - Moderation, Embeds & UI Overhaul Features Moderation System Added server roles: Owner, Admin, Mod, Member — first registered user is automatically Owner New /kick, /ban, /unban, /mute, /unmute, /role, /nuke commands for moderators and admins ModerationController with full REST API for role assignment, kicks, bans, mutes, message deletion, and channel nuking Mutes support optional duration (auto-expire) and blocked users cannot log in Role claim included in JWT tokens; role badges shown in the online users panel Kicked and banned users are forcibly disconnected in real time — server cleans up presence, broadcasts departures, and signals client disconnect Works for both SignalR and IRC connections; client shows an error dialog with the reason Private Channels Channels can be created as public or private via a checkbox in the Create Channel dialog Public channels are visible to all users; private channels only appear for members who joined them Persistent channel membership tracked in the database (ChannelMembership table) GET /api/channels returns the combined list: public channels + user's joined private channels Channel creators are automatically added as members OpenGraph Link Embeds Messages containing URLs now show a rich preview below the message text Multiple URLs per message supported (up to 3) — each gets its own embed Server-side fetching: detects URLs in a message, fetches each page, and parses OpenGraph meta tags (og:title, og:description, og:site_name) Embeds are persisted in the database as a JSON array and included in channel history TUI client renders embeds with a ▏ left border bar — site name and border in blue, title in white, description in gray; text word-wraps at actual viewport width IRC gateway receives a text-only embed preview (site name, title, description) Falls back to tag when no OG tags are present; gracefully skips if no useful metadata is found 5-second fetch timeout ensures message delivery is never significantly delayed SSRF protection rejects private/loopback IP addresses before fetching Notification Sounds Incoming messages play a notification sound when the terminal is not focused Embedded MP3 asset with cross-platform playback support Online Users Panel Collapsible right-side panel showing online users in the current channel (toggle with F2) Users displayed with status indicators, role badges, and their custom nickname colors Panel updates on join, leave, and status change events @mention Highlighting @username text rendered in orange accent color in all messages Messages mentioning the current user get a full-line amber background highlight Works across multi-line messages and continuation lines ASCII Art Improvements Half-block character rendering (▀/█) with separate foreground + background colors for 2x vertical resolution Switched from ANSI escape codes to printable color tags ({F:RRGGBB}, {B:RRGGBB}, {X}) — no control bytes in stored content Optional size parameter for /send command: -s (40x40), -m (80x80, default), -l (120x120) IRC gateway converts color tags back to ANSI for IRC client compatibility Client UI Version number shown in the status bar Custom colored rendering for channel list (active indicator, unread count badges) Avatar upload field added to the profile edit dialog (file path or URL) Profile avatar now renders with full color tag support in the profile view dialog Update check notification on connect — shows a system message if a newer GitHub release exists Chat messages no longer show selection/focus highlight Exit shortcut changed from Ctrl+C to Alt+Q — frees Ctrl+C for copy Default history increased from 50 to 100 messages on channel join Fixes Fixed #general channel not visible after adding the IsPublic column — migration default changed to true and startup service ensures it Fixed channels disappearing when creating a new channel — replaced full re-fetch with incremental updates Wired OnChannelUpdated SignalR event so new public channels appear for all connected users in real time Fixed color tag parser using wrong regex group numbers (6,7,8 instead of 1,2,3) — new ASCII art was rendering without colors Full Unicode/emoji support — renderers use Terminal.Gui v2 grapheme cluster API (GraphemeHelper, AddStr) for proper wide character handling Emoji-to-text shortcode conversion for consistent cross-platform rendering Fixed /send and /avatar commands not handling file paths with spaces correctly, even when quoted Server-side newline spam protection — consecutive blank/whitespace-only lines collapsed to 1 and total lines capped at 30 Fixed OG tag regex truncating descriptions containing apostrophes (e.g. \"HueByte's portfolio\" was cut to \"HueByte\") — switched to backreference-based quote pairing Infrastructure New LinkEmbedService on the server — URL detection, HTML fetching (first 64KB), OG tag parsing via compiled regex EmbedDto record added to shared Core DTOs; MessageDto.Embeds list for multiple embeds per message EmbedJson nullable column on the Message table stores serialized embed data as JSON array (max 8KB); DataMigrationService auto-migrates old single-object format Dedicated \"OgFetch\" named HttpClient with bot User-Agent header and 5-second timeout PresenceTracker.ForceRemoveUser() for atomic user cleanup on kick/ban IChatBroadcaster.ForceDisconnectUserAsync() and IEchoHubClient.ForceDisconnect for force-disconnect signaling NotificationSoundService for cross-platform audio playback of embedded notification sounds Startup DataMigrationService automatically converts old ANSI-format messages to the new color tag format on server boot, logging the count of migrated records EmojiHelper utility for emoji-to-shortcode conversion Heartbeat handling in ServerDirectoryService for connection health checks Four new EF Core migrations: AddModerationRoles, AddChannelIsPublic, AddChannelMembership, AddMessageEmbed ChannelMembership table with cascade delete on both channel and user removal" }, + "changelog/v0.2.4.html": { + "href": "changelog/v0.2.4.html", + "title": "v0.2.4 - E2E Message Encryption | EchoHub Documentation", + "summary": "v0.2.4 - E2E Message Encryption Features E2E Message Encryption Application-layer AES-256-GCM encryption for all message content between client and server Protects against ISPs, proxies, and any middleman reading chat messages — even if TLS is compromised 256-bit encryption key auto-generated on first server startup and saved to appsettings.json Client fetches the encryption key automatically after login via GET /api/server/encryption-key Client encrypts messages before sending via SignalR; server decrypts for validation and processing Server broadcasts encrypted content to SignalR clients; client decrypts transparently — no user action required Optional database encryption at rest via Encryption:EncryptDatabase setting (disabled by default) When enabled: new messages encrypted before DB storage (existing plaintext messages are not retroactively encrypted) When disabled: messages stored as plaintext, no risk of data loss from key rotation Reads handle mixed content (encrypted + plaintext) regardless of setting — safe to toggle at any time Key rotation is safe: old plaintext stays readable, new messages use the new key IRC gateway automatically decrypts messages before forwarding to IRC clients (plaintext over IRC) Encrypted content format: $ENC$v1${nonce}${ciphertext+tag} (Base64, 12-byte nonce, 16-byte auth tag) Server strips $ENC$ prefix from user-typed messages to prevent format spoofing Graceful fallback: if decryption fails, shows [encrypted message — decryption failed, try re-logging to fetch the latest key] Infrastructure IMessageEncryptionService interface in Core; MessageEncryptionService server implementation and ClientEncryptionService client implementation EncryptionKeyResponse DTO and GET /api/server/encryption-key endpoint (authenticated, rate-limited) FirstRunSetup.EnsureEncryptionKey() auto-generates AES-256 key on first server run Encryption:EncryptDatabase server setting (default false) controls whether messages are encrypted at rest DB column max lengths increased for encrypted content: Message.Content 2000 → 16000, Message.EmbedJson 8000 → 32000 EF Core migration: AddEncryptionSupport Encryption test suite: server-side, client-side, and cross-compatibility tests (87 total) Documentation article: docs/articles/encryption.md" + }, "index.html": { "href": "index.html", "title": "EchoHub Documentation | EchoHub Documentation", diff --git a/manifest.json b/manifest.json index 191dc75..f1abc45 100644 --- a/manifest.json +++ b/manifest.json @@ -178,6 +178,20 @@ "Title": "EchoHub.Client.Services.ApiClient", "Summary": null }, + { + "type": "ManagedReference", + "source_relative_path": "_api_meta/client/EchoHub.Client.Services.ClientEncryptionService.yml", + "output": { + ".html": { + "relative_path": "api/client/EchoHub.Client.Services.ClientEncryptionService.html" + } + }, + "version": "", + "Uid": null, + "IsMRef": true, + "Title": "EchoHub.Client.Services.ClientEncryptionService", + "Summary": "<p sourcefile=\"_api_meta/client/EchoHub.Client.Services.ClientEncryptionService.yml\" sourcestartlinenumber=\"1\">Client-side encryption service. Uses the same AES-256-GCM format as the server\nso messages are encrypted end-to-end between client and server.</p>\n" + }, { "type": "ManagedReference", "source_relative_path": "_api_meta/client/EchoHub.Client.Services.EchoHubConnection.yml", @@ -682,6 +696,20 @@ "Title": "EchoHub.Core.Contracts.IEchoHubClient", "Summary": "<p sourcefile=\"_api_meta/core/EchoHub.Core.Contracts.IEchoHubClient.yml\" sourcestartlinenumber=\"1\">Methods the server can invoke on connected clients.</p>\n" }, + { + "type": "ManagedReference", + "source_relative_path": "_api_meta/core/EchoHub.Core.Contracts.IMessageEncryptionService.yml", + "output": { + ".html": { + "relative_path": "api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html" + } + }, + "version": "", + "Uid": null, + "IsMRef": true, + "Title": "EchoHub.Core.Contracts.IMessageEncryptionService", + "Summary": null + }, { "type": "ManagedReference", "source_relative_path": "_api_meta/core/EchoHub.Core.Contracts.yml", @@ -780,6 +808,20 @@ "Title": "EchoHub.Core.DTOs.EmbedDto", "Summary": null }, + { + "type": "ManagedReference", + "source_relative_path": "_api_meta/core/EchoHub.Core.DTOs.EncryptionKeyResponse.yml", + "output": { + ".html": { + "relative_path": "api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html" + } + }, + "version": "", + "Uid": null, + "IsMRef": true, + "Title": "EchoHub.Core.DTOs.EncryptionKeyResponse", + "Summary": null + }, { "type": "ManagedReference", "source_relative_path": "_api_meta/core/EchoHub.Core.DTOs.ErrorResponse.yml", @@ -1480,6 +1522,20 @@ "Title": "EchoHub.Server.Data.Migrations.AddChannelMembership", "Summary": null }, + { + "type": "ManagedReference", + "source_relative_path": "_api_meta/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.yml", + "output": { + ".html": { + "relative_path": "api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html" + } + }, + "version": "", + "Uid": null, + "IsMRef": true, + "Title": "EchoHub.Server.Data.Migrations.AddEncryptionSupport", + "Summary": null + }, { "type": "ManagedReference", "source_relative_path": "_api_meta/server/EchoHub.Server.Data.Migrations.AddMessageEmbed.yml", @@ -1648,6 +1704,20 @@ "Title": "EchoHub.Server.Services.LinkEmbedService", "Summary": null }, + { + "type": "ManagedReference", + "source_relative_path": "_api_meta/server/EchoHub.Server.Services.MessageEncryptionService.yml", + "output": { + ".html": { + "relative_path": "api/server/EchoHub.Server.Services.MessageEncryptionService.html" + } + }, + "version": "", + "Uid": null, + "IsMRef": true, + "Title": "EchoHub.Server.Services.MessageEncryptionService", + "Summary": null + }, { "type": "ManagedReference", "source_relative_path": "_api_meta/server/EchoHub.Server.Services.PresenceTracker.yml", @@ -1862,6 +1932,16 @@ }, "version": "" }, + { + "type": "Conceptual", + "source_relative_path": "articles/encryption.md", + "output": { + ".html": { + "relative_path": "articles/encryption.html" + } + }, + "version": "" + }, { "type": "Conceptual", "source_relative_path": "articles/getting-started.md", @@ -1978,6 +2058,16 @@ }, "version": "" }, + { + "type": "Conceptual", + "source_relative_path": "changelog/v0.2.4.md", + "output": { + ".html": { + "relative_path": "changelog/v0.2.4.html" + } + }, + "version": "" + }, { "type": "Resource", "source_relative_path": "images/hue_icon.svg", diff --git a/xrefmap.yml b/xrefmap.yml index 61109ba..a30b8e0 100644 --- a/xrefmap.yml +++ b/xrefmap.yml @@ -937,6 +937,18 @@ references: commentId: Overload:EchoHub.Client.Services.ApiClient.GetChannelsAsync fullName: EchoHub.Client.Services.ApiClient.GetChannelsAsync nameWithType: ApiClient.GetChannelsAsync +- uid: EchoHub.Client.Services.ApiClient.GetEncryptionKeyAsync + name: GetEncryptionKeyAsync() + href: api/client/EchoHub.Client.Services.ApiClient.html#EchoHub_Client_Services_ApiClient_GetEncryptionKeyAsync + commentId: M:EchoHub.Client.Services.ApiClient.GetEncryptionKeyAsync + fullName: EchoHub.Client.Services.ApiClient.GetEncryptionKeyAsync() + nameWithType: ApiClient.GetEncryptionKeyAsync() +- uid: EchoHub.Client.Services.ApiClient.GetEncryptionKeyAsync* + name: GetEncryptionKeyAsync + href: api/client/EchoHub.Client.Services.ApiClient.html#EchoHub_Client_Services_ApiClient_GetEncryptionKeyAsync_ + commentId: Overload:EchoHub.Client.Services.ApiClient.GetEncryptionKeyAsync + fullName: EchoHub.Client.Services.ApiClient.GetEncryptionKeyAsync + nameWithType: ApiClient.GetEncryptionKeyAsync - uid: EchoHub.Client.Services.ApiClient.GetServerInfoAsync name: GetServerInfoAsync() href: api/client/EchoHub.Client.Services.ApiClient.html#EchoHub_Client_Services_ApiClient_GetServerInfoAsync @@ -1201,21 +1213,144 @@ references: commentId: Overload:EchoHub.Client.Services.ApiClient.UploadFileAsync fullName: EchoHub.Client.Services.ApiClient.UploadFileAsync nameWithType: ApiClient.UploadFileAsync +- uid: EchoHub.Client.Services.ClientEncryptionService + name: ClientEncryptionService + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html + commentId: T:EchoHub.Client.Services.ClientEncryptionService + fullName: EchoHub.Client.Services.ClientEncryptionService + nameWithType: ClientEncryptionService +- uid: EchoHub.Client.Services.ClientEncryptionService.#ctor + name: ClientEncryptionService() + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService__ctor + commentId: M:EchoHub.Client.Services.ClientEncryptionService.#ctor + name.vb: New() + fullName: EchoHub.Client.Services.ClientEncryptionService.ClientEncryptionService() + fullName.vb: EchoHub.Client.Services.ClientEncryptionService.New() + nameWithType: ClientEncryptionService.ClientEncryptionService() + nameWithType.vb: ClientEncryptionService.New() +- uid: EchoHub.Client.Services.ClientEncryptionService.#ctor* + name: ClientEncryptionService + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService__ctor_ + commentId: Overload:EchoHub.Client.Services.ClientEncryptionService.#ctor + name.vb: New + fullName: EchoHub.Client.Services.ClientEncryptionService.ClientEncryptionService + fullName.vb: EchoHub.Client.Services.ClientEncryptionService.New + nameWithType: ClientEncryptionService.ClientEncryptionService + nameWithType.vb: ClientEncryptionService.New +- uid: EchoHub.Client.Services.ClientEncryptionService.Decrypt(System.String) + name: Decrypt(string) + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_Decrypt_System_String_ + commentId: M:EchoHub.Client.Services.ClientEncryptionService.Decrypt(System.String) + name.vb: Decrypt(String) + fullName: EchoHub.Client.Services.ClientEncryptionService.Decrypt(string) + fullName.vb: EchoHub.Client.Services.ClientEncryptionService.Decrypt(String) + nameWithType: ClientEncryptionService.Decrypt(string) + nameWithType.vb: ClientEncryptionService.Decrypt(String) +- uid: EchoHub.Client.Services.ClientEncryptionService.Decrypt* + name: Decrypt + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_Decrypt_ + commentId: Overload:EchoHub.Client.Services.ClientEncryptionService.Decrypt + fullName: EchoHub.Client.Services.ClientEncryptionService.Decrypt + nameWithType: ClientEncryptionService.Decrypt +- uid: EchoHub.Client.Services.ClientEncryptionService.DecryptNullable(System.String) + name: DecryptNullable(string?) + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_DecryptNullable_System_String_ + commentId: M:EchoHub.Client.Services.ClientEncryptionService.DecryptNullable(System.String) + name.vb: DecryptNullable(String) + fullName: EchoHub.Client.Services.ClientEncryptionService.DecryptNullable(string?) + fullName.vb: EchoHub.Client.Services.ClientEncryptionService.DecryptNullable(String) + nameWithType: ClientEncryptionService.DecryptNullable(string?) + nameWithType.vb: ClientEncryptionService.DecryptNullable(String) +- uid: EchoHub.Client.Services.ClientEncryptionService.DecryptNullable* + name: DecryptNullable + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_DecryptNullable_ + commentId: Overload:EchoHub.Client.Services.ClientEncryptionService.DecryptNullable + fullName: EchoHub.Client.Services.ClientEncryptionService.DecryptNullable + nameWithType: ClientEncryptionService.DecryptNullable +- uid: EchoHub.Client.Services.ClientEncryptionService.Encrypt(System.String) + name: Encrypt(string) + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_Encrypt_System_String_ + commentId: M:EchoHub.Client.Services.ClientEncryptionService.Encrypt(System.String) + name.vb: Encrypt(String) + fullName: EchoHub.Client.Services.ClientEncryptionService.Encrypt(string) + fullName.vb: EchoHub.Client.Services.ClientEncryptionService.Encrypt(String) + nameWithType: ClientEncryptionService.Encrypt(string) + nameWithType.vb: ClientEncryptionService.Encrypt(String) +- uid: EchoHub.Client.Services.ClientEncryptionService.Encrypt* + name: Encrypt + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_Encrypt_ + commentId: Overload:EchoHub.Client.Services.ClientEncryptionService.Encrypt + fullName: EchoHub.Client.Services.ClientEncryptionService.Encrypt + nameWithType: ClientEncryptionService.Encrypt +- uid: EchoHub.Client.Services.ClientEncryptionService.EncryptDatabaseEnabled + name: EncryptDatabaseEnabled + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_EncryptDatabaseEnabled + commentId: P:EchoHub.Client.Services.ClientEncryptionService.EncryptDatabaseEnabled + fullName: EchoHub.Client.Services.ClientEncryptionService.EncryptDatabaseEnabled + nameWithType: ClientEncryptionService.EncryptDatabaseEnabled +- uid: EchoHub.Client.Services.ClientEncryptionService.EncryptDatabaseEnabled* + name: EncryptDatabaseEnabled + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_EncryptDatabaseEnabled_ + commentId: Overload:EchoHub.Client.Services.ClientEncryptionService.EncryptDatabaseEnabled + fullName: EchoHub.Client.Services.ClientEncryptionService.EncryptDatabaseEnabled + nameWithType: ClientEncryptionService.EncryptDatabaseEnabled +- uid: EchoHub.Client.Services.ClientEncryptionService.EncryptNullable(System.String) + name: EncryptNullable(string?) + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_EncryptNullable_System_String_ + commentId: M:EchoHub.Client.Services.ClientEncryptionService.EncryptNullable(System.String) + name.vb: EncryptNullable(String) + fullName: EchoHub.Client.Services.ClientEncryptionService.EncryptNullable(string?) + fullName.vb: EchoHub.Client.Services.ClientEncryptionService.EncryptNullable(String) + nameWithType: ClientEncryptionService.EncryptNullable(string?) + nameWithType.vb: ClientEncryptionService.EncryptNullable(String) +- uid: EchoHub.Client.Services.ClientEncryptionService.EncryptNullable* + name: EncryptNullable + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_EncryptNullable_ + commentId: Overload:EchoHub.Client.Services.ClientEncryptionService.EncryptNullable + fullName: EchoHub.Client.Services.ClientEncryptionService.EncryptNullable + nameWithType: ClientEncryptionService.EncryptNullable +- uid: EchoHub.Client.Services.ClientEncryptionService.IsInitialized + name: IsInitialized + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_IsInitialized + commentId: P:EchoHub.Client.Services.ClientEncryptionService.IsInitialized + fullName: EchoHub.Client.Services.ClientEncryptionService.IsInitialized + nameWithType: ClientEncryptionService.IsInitialized +- uid: EchoHub.Client.Services.ClientEncryptionService.IsInitialized* + name: IsInitialized + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_IsInitialized_ + commentId: Overload:EchoHub.Client.Services.ClientEncryptionService.IsInitialized + fullName: EchoHub.Client.Services.ClientEncryptionService.IsInitialized + nameWithType: ClientEncryptionService.IsInitialized +- uid: EchoHub.Client.Services.ClientEncryptionService.SetKey(System.String) + name: SetKey(string) + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_SetKey_System_String_ + commentId: M:EchoHub.Client.Services.ClientEncryptionService.SetKey(System.String) + name.vb: SetKey(String) + fullName: EchoHub.Client.Services.ClientEncryptionService.SetKey(string) + fullName.vb: EchoHub.Client.Services.ClientEncryptionService.SetKey(String) + nameWithType: ClientEncryptionService.SetKey(string) + nameWithType.vb: ClientEncryptionService.SetKey(String) +- uid: EchoHub.Client.Services.ClientEncryptionService.SetKey* + name: SetKey + href: api/client/EchoHub.Client.Services.ClientEncryptionService.html#EchoHub_Client_Services_ClientEncryptionService_SetKey_ + commentId: Overload:EchoHub.Client.Services.ClientEncryptionService.SetKey + fullName: EchoHub.Client.Services.ClientEncryptionService.SetKey + nameWithType: ClientEncryptionService.SetKey - uid: EchoHub.Client.Services.EchoHubConnection name: EchoHubConnection href: api/client/EchoHub.Client.Services.EchoHubConnection.html commentId: T:EchoHub.Client.Services.EchoHubConnection fullName: EchoHub.Client.Services.EchoHubConnection nameWithType: EchoHubConnection -- uid: EchoHub.Client.Services.EchoHubConnection.#ctor(System.String,EchoHub.Client.Services.ApiClient) - name: EchoHubConnection(string, ApiClient) - href: api/client/EchoHub.Client.Services.EchoHubConnection.html#EchoHub_Client_Services_EchoHubConnection__ctor_System_String_EchoHub_Client_Services_ApiClient_ - commentId: M:EchoHub.Client.Services.EchoHubConnection.#ctor(System.String,EchoHub.Client.Services.ApiClient) - name.vb: New(String, ApiClient) - fullName: EchoHub.Client.Services.EchoHubConnection.EchoHubConnection(string, EchoHub.Client.Services.ApiClient) - fullName.vb: EchoHub.Client.Services.EchoHubConnection.New(String, EchoHub.Client.Services.ApiClient) - nameWithType: EchoHubConnection.EchoHubConnection(string, ApiClient) - nameWithType.vb: EchoHubConnection.New(String, ApiClient) +- uid: EchoHub.Client.Services.EchoHubConnection.#ctor(System.String,EchoHub.Client.Services.ApiClient,EchoHub.Client.Services.ClientEncryptionService) + name: EchoHubConnection(string, ApiClient, ClientEncryptionService) + href: api/client/EchoHub.Client.Services.EchoHubConnection.html#EchoHub_Client_Services_EchoHubConnection__ctor_System_String_EchoHub_Client_Services_ApiClient_EchoHub_Client_Services_ClientEncryptionService_ + commentId: M:EchoHub.Client.Services.EchoHubConnection.#ctor(System.String,EchoHub.Client.Services.ApiClient,EchoHub.Client.Services.ClientEncryptionService) + name.vb: New(String, ApiClient, ClientEncryptionService) + fullName: EchoHub.Client.Services.EchoHubConnection.EchoHubConnection(string, EchoHub.Client.Services.ApiClient, EchoHub.Client.Services.ClientEncryptionService) + fullName.vb: EchoHub.Client.Services.EchoHubConnection.New(String, EchoHub.Client.Services.ApiClient, EchoHub.Client.Services.ClientEncryptionService) + nameWithType: EchoHubConnection.EchoHubConnection(string, ApiClient, ClientEncryptionService) + nameWithType.vb: EchoHubConnection.New(String, ApiClient, ClientEncryptionService) - uid: EchoHub.Client.Services.EchoHubConnection.#ctor* name: EchoHubConnection href: api/client/EchoHub.Client.Services.EchoHubConnection.html#EchoHub_Client_Services_EchoHubConnection__ctor_ @@ -5077,6 +5212,84 @@ references: commentId: Overload:EchoHub.Core.Contracts.IEchoHubClient.UserStatusChanged fullName: EchoHub.Core.Contracts.IEchoHubClient.UserStatusChanged nameWithType: IEchoHubClient.UserStatusChanged +- uid: EchoHub.Core.Contracts.IMessageEncryptionService + name: IMessageEncryptionService + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html + commentId: T:EchoHub.Core.Contracts.IMessageEncryptionService + fullName: EchoHub.Core.Contracts.IMessageEncryptionService + nameWithType: IMessageEncryptionService +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.Decrypt(System.String) + name: Decrypt(string) + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_Decrypt_System_String_ + commentId: M:EchoHub.Core.Contracts.IMessageEncryptionService.Decrypt(System.String) + name.vb: Decrypt(String) + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.Decrypt(string) + fullName.vb: EchoHub.Core.Contracts.IMessageEncryptionService.Decrypt(String) + nameWithType: IMessageEncryptionService.Decrypt(string) + nameWithType.vb: IMessageEncryptionService.Decrypt(String) +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.Decrypt* + name: Decrypt + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_Decrypt_ + commentId: Overload:EchoHub.Core.Contracts.IMessageEncryptionService.Decrypt + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.Decrypt + nameWithType: IMessageEncryptionService.Decrypt +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.DecryptNullable(System.String) + name: DecryptNullable(string?) + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_DecryptNullable_System_String_ + commentId: M:EchoHub.Core.Contracts.IMessageEncryptionService.DecryptNullable(System.String) + name.vb: DecryptNullable(String) + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.DecryptNullable(string?) + fullName.vb: EchoHub.Core.Contracts.IMessageEncryptionService.DecryptNullable(String) + nameWithType: IMessageEncryptionService.DecryptNullable(string?) + nameWithType.vb: IMessageEncryptionService.DecryptNullable(String) +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.DecryptNullable* + name: DecryptNullable + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_DecryptNullable_ + commentId: Overload:EchoHub.Core.Contracts.IMessageEncryptionService.DecryptNullable + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.DecryptNullable + nameWithType: IMessageEncryptionService.DecryptNullable +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.Encrypt(System.String) + name: Encrypt(string) + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_Encrypt_System_String_ + commentId: M:EchoHub.Core.Contracts.IMessageEncryptionService.Encrypt(System.String) + name.vb: Encrypt(String) + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.Encrypt(string) + fullName.vb: EchoHub.Core.Contracts.IMessageEncryptionService.Encrypt(String) + nameWithType: IMessageEncryptionService.Encrypt(string) + nameWithType.vb: IMessageEncryptionService.Encrypt(String) +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.Encrypt* + name: Encrypt + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_Encrypt_ + commentId: Overload:EchoHub.Core.Contracts.IMessageEncryptionService.Encrypt + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.Encrypt + nameWithType: IMessageEncryptionService.Encrypt +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.EncryptDatabaseEnabled + name: EncryptDatabaseEnabled + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_EncryptDatabaseEnabled + commentId: P:EchoHub.Core.Contracts.IMessageEncryptionService.EncryptDatabaseEnabled + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.EncryptDatabaseEnabled + nameWithType: IMessageEncryptionService.EncryptDatabaseEnabled +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.EncryptDatabaseEnabled* + name: EncryptDatabaseEnabled + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_EncryptDatabaseEnabled_ + commentId: Overload:EchoHub.Core.Contracts.IMessageEncryptionService.EncryptDatabaseEnabled + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.EncryptDatabaseEnabled + nameWithType: IMessageEncryptionService.EncryptDatabaseEnabled +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.EncryptNullable(System.String) + name: EncryptNullable(string?) + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_EncryptNullable_System_String_ + commentId: M:EchoHub.Core.Contracts.IMessageEncryptionService.EncryptNullable(System.String) + name.vb: EncryptNullable(String) + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.EncryptNullable(string?) + fullName.vb: EchoHub.Core.Contracts.IMessageEncryptionService.EncryptNullable(String) + nameWithType: IMessageEncryptionService.EncryptNullable(string?) + nameWithType.vb: IMessageEncryptionService.EncryptNullable(String) +- uid: EchoHub.Core.Contracts.IMessageEncryptionService.EncryptNullable* + name: EncryptNullable + href: api/core/EchoHub.Core.Contracts.IMessageEncryptionService.html#EchoHub_Core_Contracts_IMessageEncryptionService_EncryptNullable_ + commentId: Overload:EchoHub.Core.Contracts.IMessageEncryptionService.EncryptNullable + fullName: EchoHub.Core.Contracts.IMessageEncryptionService.EncryptNullable + nameWithType: IMessageEncryptionService.EncryptNullable - uid: EchoHub.Core.DTOs name: EchoHub.Core.DTOs href: api/core/EchoHub.Core.DTOs.html @@ -6235,6 +6448,174 @@ references: fullName.vb: EchoHub.Core.DTOs.EmbedDto.<> nameWithType: EmbedDto.operator != nameWithType.vb: EmbedDto.<> +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse + name: EncryptionKeyResponse + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html + commentId: T:EchoHub.Core.DTOs.EncryptionKeyResponse + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse + nameWithType: EncryptionKeyResponse +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.#ctor(EchoHub.Core.DTOs.EncryptionKeyResponse) + name: EncryptionKeyResponse(EncryptionKeyResponse) + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse__ctor_EchoHub_Core_DTOs_EncryptionKeyResponse_ + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.#ctor(EchoHub.Core.DTOs.EncryptionKeyResponse) + name.vb: New(EncryptionKeyResponse) + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.EncryptionKeyResponse(EchoHub.Core.DTOs.EncryptionKeyResponse) + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.New(EchoHub.Core.DTOs.EncryptionKeyResponse) + nameWithType: EncryptionKeyResponse.EncryptionKeyResponse(EncryptionKeyResponse) + nameWithType.vb: EncryptionKeyResponse.New(EncryptionKeyResponse) +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.#ctor(System.String) + name: EncryptionKeyResponse(string) + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse__ctor_System_String_ + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.#ctor(System.String) + name.vb: New(String) + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.EncryptionKeyResponse(string) + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.New(String) + nameWithType: EncryptionKeyResponse.EncryptionKeyResponse(string) + nameWithType.vb: EncryptionKeyResponse.New(String) +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.#ctor* + name: EncryptionKeyResponse + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse__ctor_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.#ctor + name.vb: New + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.EncryptionKeyResponse + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.New + nameWithType: EncryptionKeyResponse.EncryptionKeyResponse + nameWithType.vb: EncryptionKeyResponse.New +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.Deconstruct(System.String@) + name: Deconstruct(out string) + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_Deconstruct_System_String__ + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.Deconstruct(System.String@) + name.vb: Deconstruct(String) + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.Deconstruct(out string) + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.Deconstruct(String) + nameWithType: EncryptionKeyResponse.Deconstruct(out string) + nameWithType.vb: EncryptionKeyResponse.Deconstruct(String) +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.Deconstruct* + name: Deconstruct + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_Deconstruct_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.Deconstruct + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.Deconstruct + nameWithType: EncryptionKeyResponse.Deconstruct +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.EqualityContract + name: EqualityContract + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_EqualityContract + commentId: P:EchoHub.Core.DTOs.EncryptionKeyResponse.EqualityContract + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.EqualityContract + nameWithType: EncryptionKeyResponse.EqualityContract +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.EqualityContract* + name: EqualityContract + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_EqualityContract_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.EqualityContract + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.EqualityContract + nameWithType: EncryptionKeyResponse.EqualityContract +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.Equals(EchoHub.Core.DTOs.EncryptionKeyResponse) + name: Equals(EncryptionKeyResponse?) + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_Equals_EchoHub_Core_DTOs_EncryptionKeyResponse_ + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.Equals(EchoHub.Core.DTOs.EncryptionKeyResponse) + name.vb: Equals(EncryptionKeyResponse) + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.Equals(EchoHub.Core.DTOs.EncryptionKeyResponse?) + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.Equals(EchoHub.Core.DTOs.EncryptionKeyResponse) + nameWithType: EncryptionKeyResponse.Equals(EncryptionKeyResponse?) + nameWithType.vb: EncryptionKeyResponse.Equals(EncryptionKeyResponse) +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.Equals(System.Object) + name: Equals(object?) + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_Equals_System_Object_ + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.Equals(System.Object) + name.vb: Equals(Object) + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.Equals(object?) + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.Equals(Object) + nameWithType: EncryptionKeyResponse.Equals(object?) + nameWithType.vb: EncryptionKeyResponse.Equals(Object) +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.Equals* + name: Equals + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_Equals_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.Equals + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.Equals + nameWithType: EncryptionKeyResponse.Equals +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.GetHashCode + name: GetHashCode() + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_GetHashCode + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.GetHashCode + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.GetHashCode() + nameWithType: EncryptionKeyResponse.GetHashCode() +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.GetHashCode* + name: GetHashCode + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_GetHashCode_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.GetHashCode + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.GetHashCode + nameWithType: EncryptionKeyResponse.GetHashCode +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.Key + name: Key + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_Key + commentId: P:EchoHub.Core.DTOs.EncryptionKeyResponse.Key + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.Key + nameWithType: EncryptionKeyResponse.Key +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.Key* + name: Key + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_Key_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.Key + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.Key + nameWithType: EncryptionKeyResponse.Key +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.PrintMembers(System.Text.StringBuilder) + name: PrintMembers(StringBuilder) + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_PrintMembers_System_Text_StringBuilder_ + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.PrintMembers(System.Text.StringBuilder) + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.PrintMembers(System.Text.StringBuilder) + nameWithType: EncryptionKeyResponse.PrintMembers(StringBuilder) +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.PrintMembers* + name: PrintMembers + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_PrintMembers_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.PrintMembers + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.PrintMembers + nameWithType: EncryptionKeyResponse.PrintMembers +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.ToString + name: ToString() + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_ToString + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.ToString + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.ToString() + nameWithType: EncryptionKeyResponse.ToString() +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.ToString* + name: ToString + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_ToString_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.ToString + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.ToString + nameWithType: EncryptionKeyResponse.ToString +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.op_Equality(EchoHub.Core.DTOs.EncryptionKeyResponse,EchoHub.Core.DTOs.EncryptionKeyResponse) + name: operator ==(EncryptionKeyResponse?, EncryptionKeyResponse?) + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_op_Equality_EchoHub_Core_DTOs_EncryptionKeyResponse_EchoHub_Core_DTOs_EncryptionKeyResponse_ + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.op_Equality(EchoHub.Core.DTOs.EncryptionKeyResponse,EchoHub.Core.DTOs.EncryptionKeyResponse) + name.vb: =(EncryptionKeyResponse, EncryptionKeyResponse) + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.operator ==(EchoHub.Core.DTOs.EncryptionKeyResponse?, EchoHub.Core.DTOs.EncryptionKeyResponse?) + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.=(EchoHub.Core.DTOs.EncryptionKeyResponse, EchoHub.Core.DTOs.EncryptionKeyResponse) + nameWithType: EncryptionKeyResponse.operator ==(EncryptionKeyResponse?, EncryptionKeyResponse?) + nameWithType.vb: EncryptionKeyResponse.=(EncryptionKeyResponse, EncryptionKeyResponse) +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.op_Equality* + name: operator == + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_op_Equality_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.op_Equality + name.vb: = + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.operator == + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.= + nameWithType: EncryptionKeyResponse.operator == + nameWithType.vb: EncryptionKeyResponse.= +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.op_Inequality(EchoHub.Core.DTOs.EncryptionKeyResponse,EchoHub.Core.DTOs.EncryptionKeyResponse) + name: operator !=(EncryptionKeyResponse?, EncryptionKeyResponse?) + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_op_Inequality_EchoHub_Core_DTOs_EncryptionKeyResponse_EchoHub_Core_DTOs_EncryptionKeyResponse_ + commentId: M:EchoHub.Core.DTOs.EncryptionKeyResponse.op_Inequality(EchoHub.Core.DTOs.EncryptionKeyResponse,EchoHub.Core.DTOs.EncryptionKeyResponse) + name.vb: <>(EncryptionKeyResponse, EncryptionKeyResponse) + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.operator !=(EchoHub.Core.DTOs.EncryptionKeyResponse?, EchoHub.Core.DTOs.EncryptionKeyResponse?) + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.<>(EchoHub.Core.DTOs.EncryptionKeyResponse, EchoHub.Core.DTOs.EncryptionKeyResponse) + nameWithType: EncryptionKeyResponse.operator !=(EncryptionKeyResponse?, EncryptionKeyResponse?) + nameWithType.vb: EncryptionKeyResponse.<>(EncryptionKeyResponse, EncryptionKeyResponse) +- uid: EchoHub.Core.DTOs.EncryptionKeyResponse.op_Inequality* + name: operator != + href: api/core/EchoHub.Core.DTOs.EncryptionKeyResponse.html#EchoHub_Core_DTOs_EncryptionKeyResponse_op_Inequality_ + commentId: Overload:EchoHub.Core.DTOs.EncryptionKeyResponse.op_Inequality + name.vb: <> + fullName: EchoHub.Core.DTOs.EncryptionKeyResponse.operator != + fullName.vb: EchoHub.Core.DTOs.EncryptionKeyResponse.<> + nameWithType: EncryptionKeyResponse.operator != + nameWithType.vb: EncryptionKeyResponse.<> - uid: EchoHub.Core.DTOs.ErrorResponse name: ErrorResponse href: api/core/EchoHub.Core.DTOs.ErrorResponse.html @@ -10807,15 +11188,15 @@ references: commentId: T:EchoHub.Server.Controllers.ChannelsController fullName: EchoHub.Server.Controllers.ChannelsController nameWithType: ChannelsController -- uid: EchoHub.Server.Controllers.ChannelsController.#ctor(EchoHub.Server.Data.EchoHubDbContext,EchoHub.Server.Services.FileStorageService,EchoHub.Server.Services.ImageToAsciiService,System.Net.Http.IHttpClientFactory,EchoHub.Core.Contracts.IChatService) - name: ChannelsController(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService) - href: api/server/EchoHub.Server.Controllers.ChannelsController.html#EchoHub_Server_Controllers_ChannelsController__ctor_EchoHub_Server_Data_EchoHubDbContext_EchoHub_Server_Services_FileStorageService_EchoHub_Server_Services_ImageToAsciiService_System_Net_Http_IHttpClientFactory_EchoHub_Core_Contracts_IChatService_ - commentId: M:EchoHub.Server.Controllers.ChannelsController.#ctor(EchoHub.Server.Data.EchoHubDbContext,EchoHub.Server.Services.FileStorageService,EchoHub.Server.Services.ImageToAsciiService,System.Net.Http.IHttpClientFactory,EchoHub.Core.Contracts.IChatService) - name.vb: New(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService) - fullName: EchoHub.Server.Controllers.ChannelsController.ChannelsController(EchoHub.Server.Data.EchoHubDbContext, EchoHub.Server.Services.FileStorageService, EchoHub.Server.Services.ImageToAsciiService, System.Net.Http.IHttpClientFactory, EchoHub.Core.Contracts.IChatService) - fullName.vb: EchoHub.Server.Controllers.ChannelsController.New(EchoHub.Server.Data.EchoHubDbContext, EchoHub.Server.Services.FileStorageService, EchoHub.Server.Services.ImageToAsciiService, System.Net.Http.IHttpClientFactory, EchoHub.Core.Contracts.IChatService) - nameWithType: ChannelsController.ChannelsController(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService) - nameWithType.vb: ChannelsController.New(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService) +- uid: EchoHub.Server.Controllers.ChannelsController.#ctor(EchoHub.Server.Data.EchoHubDbContext,EchoHub.Server.Services.FileStorageService,EchoHub.Server.Services.ImageToAsciiService,System.Net.Http.IHttpClientFactory,EchoHub.Core.Contracts.IChatService,EchoHub.Core.Contracts.IMessageEncryptionService) + name: ChannelsController(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService, IMessageEncryptionService) + href: api/server/EchoHub.Server.Controllers.ChannelsController.html#EchoHub_Server_Controllers_ChannelsController__ctor_EchoHub_Server_Data_EchoHubDbContext_EchoHub_Server_Services_FileStorageService_EchoHub_Server_Services_ImageToAsciiService_System_Net_Http_IHttpClientFactory_EchoHub_Core_Contracts_IChatService_EchoHub_Core_Contracts_IMessageEncryptionService_ + commentId: M:EchoHub.Server.Controllers.ChannelsController.#ctor(EchoHub.Server.Data.EchoHubDbContext,EchoHub.Server.Services.FileStorageService,EchoHub.Server.Services.ImageToAsciiService,System.Net.Http.IHttpClientFactory,EchoHub.Core.Contracts.IChatService,EchoHub.Core.Contracts.IMessageEncryptionService) + name.vb: New(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService, IMessageEncryptionService) + fullName: EchoHub.Server.Controllers.ChannelsController.ChannelsController(EchoHub.Server.Data.EchoHubDbContext, EchoHub.Server.Services.FileStorageService, EchoHub.Server.Services.ImageToAsciiService, System.Net.Http.IHttpClientFactory, EchoHub.Core.Contracts.IChatService, EchoHub.Core.Contracts.IMessageEncryptionService) + fullName.vb: EchoHub.Server.Controllers.ChannelsController.New(EchoHub.Server.Data.EchoHubDbContext, EchoHub.Server.Services.FileStorageService, EchoHub.Server.Services.ImageToAsciiService, System.Net.Http.IHttpClientFactory, EchoHub.Core.Contracts.IChatService, EchoHub.Core.Contracts.IMessageEncryptionService) + nameWithType: ChannelsController.ChannelsController(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService, IMessageEncryptionService) + nameWithType.vb: ChannelsController.New(EchoHubDbContext, FileStorageService, ImageToAsciiService, IHttpClientFactory, IChatService, IMessageEncryptionService) - uid: EchoHub.Server.Controllers.ChannelsController.#ctor* name: ChannelsController href: api/server/EchoHub.Server.Controllers.ChannelsController.html#EchoHub_Server_Controllers_ChannelsController__ctor_ @@ -11113,6 +11494,18 @@ references: fullName.vb: EchoHub.Server.Controllers.ServerController.New nameWithType: ServerController.ServerController nameWithType.vb: ServerController.New +- uid: EchoHub.Server.Controllers.ServerController.GetEncryptionKey + name: GetEncryptionKey() + href: api/server/EchoHub.Server.Controllers.ServerController.html#EchoHub_Server_Controllers_ServerController_GetEncryptionKey + commentId: M:EchoHub.Server.Controllers.ServerController.GetEncryptionKey + fullName: EchoHub.Server.Controllers.ServerController.GetEncryptionKey() + nameWithType: ServerController.GetEncryptionKey() +- uid: EchoHub.Server.Controllers.ServerController.GetEncryptionKey* + name: GetEncryptionKey + href: api/server/EchoHub.Server.Controllers.ServerController.html#EchoHub_Server_Controllers_ServerController_GetEncryptionKey_ + commentId: Overload:EchoHub.Server.Controllers.ServerController.GetEncryptionKey + fullName: EchoHub.Server.Controllers.ServerController.GetEncryptionKey + nameWithType: ServerController.GetEncryptionKey - uid: EchoHub.Server.Controllers.ServerController.GetInfo name: GetInfo() href: api/server/EchoHub.Server.Controllers.ServerController.html#EchoHub_Server_Controllers_ServerController_GetInfo @@ -11428,6 +11821,66 @@ references: commentId: Overload:EchoHub.Server.Data.Migrations.AddChannelMembership.Up fullName: EchoHub.Server.Data.Migrations.AddChannelMembership.Up nameWithType: AddChannelMembership.Up +- uid: EchoHub.Server.Data.Migrations.AddEncryptionSupport + name: AddEncryptionSupport + href: api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html + commentId: T:EchoHub.Server.Data.Migrations.AddEncryptionSupport + fullName: EchoHub.Server.Data.Migrations.AddEncryptionSupport + nameWithType: AddEncryptionSupport +- uid: EchoHub.Server.Data.Migrations.AddEncryptionSupport.#ctor + name: AddEncryptionSupport() + href: api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html#EchoHub_Server_Data_Migrations_AddEncryptionSupport__ctor + commentId: M:EchoHub.Server.Data.Migrations.AddEncryptionSupport.#ctor + name.vb: New() + fullName: EchoHub.Server.Data.Migrations.AddEncryptionSupport.AddEncryptionSupport() + fullName.vb: EchoHub.Server.Data.Migrations.AddEncryptionSupport.New() + nameWithType: AddEncryptionSupport.AddEncryptionSupport() + nameWithType.vb: AddEncryptionSupport.New() +- uid: EchoHub.Server.Data.Migrations.AddEncryptionSupport.#ctor* + name: AddEncryptionSupport + href: api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html#EchoHub_Server_Data_Migrations_AddEncryptionSupport__ctor_ + commentId: Overload:EchoHub.Server.Data.Migrations.AddEncryptionSupport.#ctor + name.vb: New + fullName: EchoHub.Server.Data.Migrations.AddEncryptionSupport.AddEncryptionSupport + fullName.vb: EchoHub.Server.Data.Migrations.AddEncryptionSupport.New + nameWithType: AddEncryptionSupport.AddEncryptionSupport + nameWithType.vb: AddEncryptionSupport.New +- uid: EchoHub.Server.Data.Migrations.AddEncryptionSupport.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder) + name: BuildTargetModel(ModelBuilder) + href: api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html#EchoHub_Server_Data_Migrations_AddEncryptionSupport_BuildTargetModel_Microsoft_EntityFrameworkCore_ModelBuilder_ + commentId: M:EchoHub.Server.Data.Migrations.AddEncryptionSupport.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder) + fullName: EchoHub.Server.Data.Migrations.AddEncryptionSupport.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder) + nameWithType: AddEncryptionSupport.BuildTargetModel(ModelBuilder) +- uid: EchoHub.Server.Data.Migrations.AddEncryptionSupport.BuildTargetModel* + name: BuildTargetModel + href: api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html#EchoHub_Server_Data_Migrations_AddEncryptionSupport_BuildTargetModel_ + commentId: Overload:EchoHub.Server.Data.Migrations.AddEncryptionSupport.BuildTargetModel + fullName: EchoHub.Server.Data.Migrations.AddEncryptionSupport.BuildTargetModel + nameWithType: AddEncryptionSupport.BuildTargetModel +- uid: EchoHub.Server.Data.Migrations.AddEncryptionSupport.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder) + name: Down(MigrationBuilder) + href: api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html#EchoHub_Server_Data_Migrations_AddEncryptionSupport_Down_Microsoft_EntityFrameworkCore_Migrations_MigrationBuilder_ + commentId: M:EchoHub.Server.Data.Migrations.AddEncryptionSupport.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder) + fullName: EchoHub.Server.Data.Migrations.AddEncryptionSupport.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder) + nameWithType: AddEncryptionSupport.Down(MigrationBuilder) +- uid: EchoHub.Server.Data.Migrations.AddEncryptionSupport.Down* + name: Down + href: api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html#EchoHub_Server_Data_Migrations_AddEncryptionSupport_Down_ + commentId: Overload:EchoHub.Server.Data.Migrations.AddEncryptionSupport.Down + fullName: EchoHub.Server.Data.Migrations.AddEncryptionSupport.Down + nameWithType: AddEncryptionSupport.Down +- uid: EchoHub.Server.Data.Migrations.AddEncryptionSupport.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder) + name: Up(MigrationBuilder) + href: api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html#EchoHub_Server_Data_Migrations_AddEncryptionSupport_Up_Microsoft_EntityFrameworkCore_Migrations_MigrationBuilder_ + commentId: M:EchoHub.Server.Data.Migrations.AddEncryptionSupport.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder) + fullName: EchoHub.Server.Data.Migrations.AddEncryptionSupport.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder) + nameWithType: AddEncryptionSupport.Up(MigrationBuilder) +- uid: EchoHub.Server.Data.Migrations.AddEncryptionSupport.Up* + name: Up + href: api/server/EchoHub.Server.Data.Migrations.AddEncryptionSupport.html#EchoHub_Server_Data_Migrations_AddEncryptionSupport_Up_ + commentId: Overload:EchoHub.Server.Data.Migrations.AddEncryptionSupport.Up + fullName: EchoHub.Server.Data.Migrations.AddEncryptionSupport.Up + nameWithType: AddEncryptionSupport.Up - uid: EchoHub.Server.Data.Migrations.AddMessageEmbed name: AddMessageEmbed href: api/server/EchoHub.Server.Data.Migrations.AddMessageEmbed.html @@ -11767,15 +12220,15 @@ references: commentId: T:EchoHub.Server.Irc.IrcBroadcaster fullName: EchoHub.Server.Irc.IrcBroadcaster nameWithType: IrcBroadcaster -- uid: EchoHub.Server.Irc.IrcBroadcaster.#ctor(EchoHub.Server.Irc.IrcGatewayService) - name: IrcBroadcaster(IrcGatewayService) - href: api/server-irc/EchoHub.Server.Irc.IrcBroadcaster.html#EchoHub_Server_Irc_IrcBroadcaster__ctor_EchoHub_Server_Irc_IrcGatewayService_ - commentId: M:EchoHub.Server.Irc.IrcBroadcaster.#ctor(EchoHub.Server.Irc.IrcGatewayService) - name.vb: New(IrcGatewayService) - fullName: EchoHub.Server.Irc.IrcBroadcaster.IrcBroadcaster(EchoHub.Server.Irc.IrcGatewayService) - fullName.vb: EchoHub.Server.Irc.IrcBroadcaster.New(EchoHub.Server.Irc.IrcGatewayService) - nameWithType: IrcBroadcaster.IrcBroadcaster(IrcGatewayService) - nameWithType.vb: IrcBroadcaster.New(IrcGatewayService) +- uid: EchoHub.Server.Irc.IrcBroadcaster.#ctor(EchoHub.Server.Irc.IrcGatewayService,EchoHub.Core.Contracts.IMessageEncryptionService) + name: IrcBroadcaster(IrcGatewayService, IMessageEncryptionService) + href: api/server-irc/EchoHub.Server.Irc.IrcBroadcaster.html#EchoHub_Server_Irc_IrcBroadcaster__ctor_EchoHub_Server_Irc_IrcGatewayService_EchoHub_Core_Contracts_IMessageEncryptionService_ + commentId: M:EchoHub.Server.Irc.IrcBroadcaster.#ctor(EchoHub.Server.Irc.IrcGatewayService,EchoHub.Core.Contracts.IMessageEncryptionService) + name.vb: New(IrcGatewayService, IMessageEncryptionService) + fullName: EchoHub.Server.Irc.IrcBroadcaster.IrcBroadcaster(EchoHub.Server.Irc.IrcGatewayService, EchoHub.Core.Contracts.IMessageEncryptionService) + fullName.vb: EchoHub.Server.Irc.IrcBroadcaster.New(EchoHub.Server.Irc.IrcGatewayService, EchoHub.Core.Contracts.IMessageEncryptionService) + nameWithType: IrcBroadcaster.IrcBroadcaster(IrcGatewayService, IMessageEncryptionService) + nameWithType.vb: IrcBroadcaster.New(IrcGatewayService, IMessageEncryptionService) - uid: EchoHub.Server.Irc.IrcBroadcaster.#ctor* name: IrcBroadcaster href: api/server-irc/EchoHub.Server.Irc.IrcBroadcaster.html#EchoHub_Server_Irc_IrcBroadcaster__ctor_ @@ -12883,15 +13336,15 @@ references: commentId: T:EchoHub.Server.Services.ChatService fullName: EchoHub.Server.Services.ChatService nameWithType: ChatService -- uid: EchoHub.Server.Services.ChatService.#ctor(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,EchoHub.Server.Services.PresenceTracker,System.Collections.Generic.IEnumerable{EchoHub.Core.Contracts.IChatBroadcaster},EchoHub.Server.Services.LinkEmbedService,Microsoft.Extensions.Logging.ILogger{EchoHub.Server.Services.ChatService}) - name: ChatService(IServiceScopeFactory, PresenceTracker, IEnumerable<IChatBroadcaster>, LinkEmbedService, ILogger<ChatService>) - href: api/server/EchoHub.Server.Services.ChatService.html#EchoHub_Server_Services_ChatService__ctor_Microsoft_Extensions_DependencyInjection_IServiceScopeFactory_EchoHub_Server_Services_PresenceTracker_System_Collections_Generic_IEnumerable_EchoHub_Core_Contracts_IChatBroadcaster__EchoHub_Server_Services_LinkEmbedService_Microsoft_Extensions_Logging_ILogger_EchoHub_Server_Services_ChatService__ - commentId: M:EchoHub.Server.Services.ChatService.#ctor(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,EchoHub.Server.Services.PresenceTracker,System.Collections.Generic.IEnumerable{EchoHub.Core.Contracts.IChatBroadcaster},EchoHub.Server.Services.LinkEmbedService,Microsoft.Extensions.Logging.ILogger{EchoHub.Server.Services.ChatService}) - name.vb: New(IServiceScopeFactory, PresenceTracker, IEnumerable(Of IChatBroadcaster), LinkEmbedService, ILogger(Of ChatService)) - fullName: EchoHub.Server.Services.ChatService.ChatService(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory, EchoHub.Server.Services.PresenceTracker, System.Collections.Generic.IEnumerable<EchoHub.Core.Contracts.IChatBroadcaster>, EchoHub.Server.Services.LinkEmbedService, Microsoft.Extensions.Logging.ILogger<EchoHub.Server.Services.ChatService>) - fullName.vb: EchoHub.Server.Services.ChatService.New(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory, EchoHub.Server.Services.PresenceTracker, System.Collections.Generic.IEnumerable(Of EchoHub.Core.Contracts.IChatBroadcaster), EchoHub.Server.Services.LinkEmbedService, Microsoft.Extensions.Logging.ILogger(Of EchoHub.Server.Services.ChatService)) - nameWithType: ChatService.ChatService(IServiceScopeFactory, PresenceTracker, IEnumerable<IChatBroadcaster>, LinkEmbedService, ILogger<ChatService>) - nameWithType.vb: ChatService.New(IServiceScopeFactory, PresenceTracker, IEnumerable(Of IChatBroadcaster), LinkEmbedService, ILogger(Of ChatService)) +- uid: EchoHub.Server.Services.ChatService.#ctor(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,EchoHub.Server.Services.PresenceTracker,System.Collections.Generic.IEnumerable{EchoHub.Core.Contracts.IChatBroadcaster},EchoHub.Server.Services.LinkEmbedService,EchoHub.Core.Contracts.IMessageEncryptionService,Microsoft.Extensions.Logging.ILogger{EchoHub.Server.Services.ChatService}) + name: ChatService(IServiceScopeFactory, PresenceTracker, IEnumerable<IChatBroadcaster>, LinkEmbedService, IMessageEncryptionService, ILogger<ChatService>) + href: api/server/EchoHub.Server.Services.ChatService.html#EchoHub_Server_Services_ChatService__ctor_Microsoft_Extensions_DependencyInjection_IServiceScopeFactory_EchoHub_Server_Services_PresenceTracker_System_Collections_Generic_IEnumerable_EchoHub_Core_Contracts_IChatBroadcaster__EchoHub_Server_Services_LinkEmbedService_EchoHub_Core_Contracts_IMessageEncryptionService_Microsoft_Extensions_Logging_ILogger_EchoHub_Server_Services_ChatService__ + commentId: M:EchoHub.Server.Services.ChatService.#ctor(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,EchoHub.Server.Services.PresenceTracker,System.Collections.Generic.IEnumerable{EchoHub.Core.Contracts.IChatBroadcaster},EchoHub.Server.Services.LinkEmbedService,EchoHub.Core.Contracts.IMessageEncryptionService,Microsoft.Extensions.Logging.ILogger{EchoHub.Server.Services.ChatService}) + name.vb: New(IServiceScopeFactory, PresenceTracker, IEnumerable(Of IChatBroadcaster), LinkEmbedService, IMessageEncryptionService, ILogger(Of ChatService)) + fullName: EchoHub.Server.Services.ChatService.ChatService(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory, EchoHub.Server.Services.PresenceTracker, System.Collections.Generic.IEnumerable<EchoHub.Core.Contracts.IChatBroadcaster>, EchoHub.Server.Services.LinkEmbedService, EchoHub.Core.Contracts.IMessageEncryptionService, Microsoft.Extensions.Logging.ILogger<EchoHub.Server.Services.ChatService>) + fullName.vb: EchoHub.Server.Services.ChatService.New(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory, EchoHub.Server.Services.PresenceTracker, System.Collections.Generic.IEnumerable(Of EchoHub.Core.Contracts.IChatBroadcaster), EchoHub.Server.Services.LinkEmbedService, EchoHub.Core.Contracts.IMessageEncryptionService, Microsoft.Extensions.Logging.ILogger(Of EchoHub.Server.Services.ChatService)) + nameWithType: ChatService.ChatService(IServiceScopeFactory, PresenceTracker, IEnumerable<IChatBroadcaster>, LinkEmbedService, IMessageEncryptionService, ILogger<ChatService>) + nameWithType.vb: ChatService.New(IServiceScopeFactory, PresenceTracker, IEnumerable(Of IChatBroadcaster), LinkEmbedService, IMessageEncryptionService, ILogger(Of ChatService)) - uid: EchoHub.Server.Services.ChatService.#ctor* name: ChatService href: api/server/EchoHub.Server.Services.ChatService.html#EchoHub_Server_Services_ChatService__ctor_ @@ -13303,6 +13756,102 @@ references: commentId: Overload:EchoHub.Server.Services.LinkEmbedService.TryGetEmbedsAsync fullName: EchoHub.Server.Services.LinkEmbedService.TryGetEmbedsAsync nameWithType: LinkEmbedService.TryGetEmbedsAsync +- uid: EchoHub.Server.Services.MessageEncryptionService + name: MessageEncryptionService + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html + commentId: T:EchoHub.Server.Services.MessageEncryptionService + fullName: EchoHub.Server.Services.MessageEncryptionService + nameWithType: MessageEncryptionService +- uid: EchoHub.Server.Services.MessageEncryptionService.#ctor(Microsoft.Extensions.Configuration.IConfiguration,Microsoft.Extensions.Logging.ILogger{EchoHub.Server.Services.MessageEncryptionService}) + name: MessageEncryptionService(IConfiguration, ILogger<MessageEncryptionService>) + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService__ctor_Microsoft_Extensions_Configuration_IConfiguration_Microsoft_Extensions_Logging_ILogger_EchoHub_Server_Services_MessageEncryptionService__ + commentId: M:EchoHub.Server.Services.MessageEncryptionService.#ctor(Microsoft.Extensions.Configuration.IConfiguration,Microsoft.Extensions.Logging.ILogger{EchoHub.Server.Services.MessageEncryptionService}) + name.vb: New(IConfiguration, ILogger(Of MessageEncryptionService)) + fullName: EchoHub.Server.Services.MessageEncryptionService.MessageEncryptionService(Microsoft.Extensions.Configuration.IConfiguration, Microsoft.Extensions.Logging.ILogger<EchoHub.Server.Services.MessageEncryptionService>) + fullName.vb: EchoHub.Server.Services.MessageEncryptionService.New(Microsoft.Extensions.Configuration.IConfiguration, Microsoft.Extensions.Logging.ILogger(Of EchoHub.Server.Services.MessageEncryptionService)) + nameWithType: MessageEncryptionService.MessageEncryptionService(IConfiguration, ILogger<MessageEncryptionService>) + nameWithType.vb: MessageEncryptionService.New(IConfiguration, ILogger(Of MessageEncryptionService)) +- uid: EchoHub.Server.Services.MessageEncryptionService.#ctor* + name: MessageEncryptionService + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService__ctor_ + commentId: Overload:EchoHub.Server.Services.MessageEncryptionService.#ctor + name.vb: New + fullName: EchoHub.Server.Services.MessageEncryptionService.MessageEncryptionService + fullName.vb: EchoHub.Server.Services.MessageEncryptionService.New + nameWithType: MessageEncryptionService.MessageEncryptionService + nameWithType.vb: MessageEncryptionService.New +- uid: EchoHub.Server.Services.MessageEncryptionService.Decrypt(System.String) + name: Decrypt(string) + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_Decrypt_System_String_ + commentId: M:EchoHub.Server.Services.MessageEncryptionService.Decrypt(System.String) + name.vb: Decrypt(String) + fullName: EchoHub.Server.Services.MessageEncryptionService.Decrypt(string) + fullName.vb: EchoHub.Server.Services.MessageEncryptionService.Decrypt(String) + nameWithType: MessageEncryptionService.Decrypt(string) + nameWithType.vb: MessageEncryptionService.Decrypt(String) +- uid: EchoHub.Server.Services.MessageEncryptionService.Decrypt* + name: Decrypt + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_Decrypt_ + commentId: Overload:EchoHub.Server.Services.MessageEncryptionService.Decrypt + fullName: EchoHub.Server.Services.MessageEncryptionService.Decrypt + nameWithType: MessageEncryptionService.Decrypt +- uid: EchoHub.Server.Services.MessageEncryptionService.DecryptNullable(System.String) + name: DecryptNullable(string?) + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_DecryptNullable_System_String_ + commentId: M:EchoHub.Server.Services.MessageEncryptionService.DecryptNullable(System.String) + name.vb: DecryptNullable(String) + fullName: EchoHub.Server.Services.MessageEncryptionService.DecryptNullable(string?) + fullName.vb: EchoHub.Server.Services.MessageEncryptionService.DecryptNullable(String) + nameWithType: MessageEncryptionService.DecryptNullable(string?) + nameWithType.vb: MessageEncryptionService.DecryptNullable(String) +- uid: EchoHub.Server.Services.MessageEncryptionService.DecryptNullable* + name: DecryptNullable + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_DecryptNullable_ + commentId: Overload:EchoHub.Server.Services.MessageEncryptionService.DecryptNullable + fullName: EchoHub.Server.Services.MessageEncryptionService.DecryptNullable + nameWithType: MessageEncryptionService.DecryptNullable +- uid: EchoHub.Server.Services.MessageEncryptionService.Encrypt(System.String) + name: Encrypt(string) + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_Encrypt_System_String_ + commentId: M:EchoHub.Server.Services.MessageEncryptionService.Encrypt(System.String) + name.vb: Encrypt(String) + fullName: EchoHub.Server.Services.MessageEncryptionService.Encrypt(string) + fullName.vb: EchoHub.Server.Services.MessageEncryptionService.Encrypt(String) + nameWithType: MessageEncryptionService.Encrypt(string) + nameWithType.vb: MessageEncryptionService.Encrypt(String) +- uid: EchoHub.Server.Services.MessageEncryptionService.Encrypt* + name: Encrypt + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_Encrypt_ + commentId: Overload:EchoHub.Server.Services.MessageEncryptionService.Encrypt + fullName: EchoHub.Server.Services.MessageEncryptionService.Encrypt + nameWithType: MessageEncryptionService.Encrypt +- uid: EchoHub.Server.Services.MessageEncryptionService.EncryptDatabaseEnabled + name: EncryptDatabaseEnabled + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_EncryptDatabaseEnabled + commentId: P:EchoHub.Server.Services.MessageEncryptionService.EncryptDatabaseEnabled + fullName: EchoHub.Server.Services.MessageEncryptionService.EncryptDatabaseEnabled + nameWithType: MessageEncryptionService.EncryptDatabaseEnabled +- uid: EchoHub.Server.Services.MessageEncryptionService.EncryptDatabaseEnabled* + name: EncryptDatabaseEnabled + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_EncryptDatabaseEnabled_ + commentId: Overload:EchoHub.Server.Services.MessageEncryptionService.EncryptDatabaseEnabled + fullName: EchoHub.Server.Services.MessageEncryptionService.EncryptDatabaseEnabled + nameWithType: MessageEncryptionService.EncryptDatabaseEnabled +- uid: EchoHub.Server.Services.MessageEncryptionService.EncryptNullable(System.String) + name: EncryptNullable(string?) + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_EncryptNullable_System_String_ + commentId: M:EchoHub.Server.Services.MessageEncryptionService.EncryptNullable(System.String) + name.vb: EncryptNullable(String) + fullName: EchoHub.Server.Services.MessageEncryptionService.EncryptNullable(string?) + fullName.vb: EchoHub.Server.Services.MessageEncryptionService.EncryptNullable(String) + nameWithType: MessageEncryptionService.EncryptNullable(string?) + nameWithType.vb: MessageEncryptionService.EncryptNullable(String) +- uid: EchoHub.Server.Services.MessageEncryptionService.EncryptNullable* + name: EncryptNullable + href: api/server/EchoHub.Server.Services.MessageEncryptionService.html#EchoHub_Server_Services_MessageEncryptionService_EncryptNullable_ + commentId: Overload:EchoHub.Server.Services.MessageEncryptionService.EncryptNullable + fullName: EchoHub.Server.Services.MessageEncryptionService.EncryptNullable + nameWithType: MessageEncryptionService.EncryptNullable - uid: EchoHub.Server.Services.PresenceTracker name: PresenceTracker href: api/server/EchoHub.Server.Services.PresenceTracker.html