using System.Text.Json; using System; using WebSocketSharp.Server; using WebSocketSharp; using RelayServer.Models; using RelayServer.Services; var surrealService = new SurrealService(); var coreClient = new CoreClientService(); var cryptoService = new ChannelCryptoService(); await using var db = await surrealService.ConnectAsync(); var wssv = new WebSocketServer("ws://localhost:1337"); wssv.AddWebSocketService("/"); wssv.Start(); Console.WriteLine("WebSocket server started"); Console.ReadKey(true); wssv.Stop(); var keeper = await coreClient.GetUserByUsernameAsync("Keeper317"); var kira = await coreClient.GetUserByUsernameAsync("Ru_Kira"); if (keeper is null || kira is null) { Console.WriteLine("One or more required users do not exist in RelayCore."); return; } if (!keeper.Licensed || !kira.Licensed) { Console.WriteLine("One or more required users are not licensed."); return; } Console.WriteLine($"Core verified user: {keeper.Username}"); Console.WriteLine($"Core verified user: {kira.Username}"); var server = await db.Create("servers", new Servers { Name = "Test Server", OwnerUserId = kira.Id, CreatedAt = DateTime.UtcNow }); Console.WriteLine($"Server created: {ToJsonString(server)}"); var keeperMember = await db.Create("server_members", new ServerMembers { UserId = keeper.Id, JoinedAt = DateTime.UtcNow, IsOwner = true }); var kiraMember = await db.Create("server_members", new ServerMembers { UserId = kira.Id, JoinedAt = DateTime.UtcNow, IsOwner = false }); Console.WriteLine("Server members created."); var channel = await db.Create("channels", new Channels { Name = "general", CreatedAt = DateTime.UtcNow }); Console.WriteLine($"Channel created: {ToJsonString(channel)}"); var channelId = GetRecordId(channel.Id); Console.WriteLine($"Resolved channelId: {channelId}"); var keyBase64 = cryptoService.GenerateKey(); var serverKey = await db.Create("server_encryption_keys", new ServerEncryptionKeys { KeyBase64 = keyBase64, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }); Console.WriteLine("Server encryption key created."); var encrypted = cryptoService.Encrypt("hello from Keeper317 in #general", keyBase64); var savedMessage = await db.Create("channel_messages", new ChannelMessages { ChannelId = channelId, SenderUserId = keeper.Id, CipherText = encrypted.cipherText, Nonce = encrypted.nonce, Tag = encrypted.tag, CreatedAt = DateTime.UtcNow }); Console.WriteLine($"Encrypted message saved: {ToJsonString(savedMessage)}"); var decrypted = cryptoService.Decrypt( savedMessage.CipherText, savedMessage.Nonce, savedMessage.Tag, keyBase64 ); var storedMessages = await db.Select("channel_messages"); Console.WriteLine("Stored DB messages:"); Console.WriteLine(ToJsonString(storedMessages)); Console.WriteLine(); Console.WriteLine($"Decrypted message: {decrypted}"); Console.WriteLine(); Console.WriteLine("Simulating Kira reading #general..."); var kiraVisibleMessages = storedMessages .Where(m => m.ChannelId == channelId) .OrderBy(m => m.CreatedAt) .ToList(); foreach (var msg in kiraVisibleMessages) { var plainText = cryptoService.Decrypt( msg.CipherText, msg.Nonce, msg.Tag, keyBase64 ); Console.WriteLine($"Kira reads message from {msg.SenderUserId}: {plainText}"); } return; static string ToJsonString(object? obj) { return JsonSerializer.Serialize(obj, new JsonSerializerOptions { WriteIndented = true, Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping }); } static string GetRecordId(object? id) { if (id is null) return string.Empty; var json = JsonSerializer.Serialize(id); using var doc = JsonDocument.Parse(json); var root = doc.RootElement; var recordId = root.GetProperty("Id").GetString() ?? string.Empty; var table = root.GetProperty("Table").GetString() ?? string.Empty; return $"{table}:{recordId}"; } public class ChatTest : WebSocketBehavior { protected override void OnMessage(MessageEventArgs e) { // var msg = e.Data.Split(":")[1] == "PING" ? "SERVER:PONG" : "SERVER:RESPONSE"; var msg = e.Data; Console.WriteLine(msg); Send(msg); } }