using SurrealDb.Net; using SurrealDb.Net.Models; using SurrealDb.Net.Models.Auth; using System.Text.Json; using PasswordHasher; using RelayCore; using var db = new SurrealDbClient("ws://127.0.0.1:8000/rpc"); await db.SignIn(new RootAuth { Username = "root", Password = "secret" }); await db.Use("test", "test"); var keeper = await CreateUserAsync(db, "Keeper317", "Keeper317@gmail.com", "password"); var kira = await CreateUserAsync(db, "Ru_Kira", "jduesling13@gmail.com", "password"); Console.WriteLine($"Keeper created: {ToJsonString(keeper)}"); Console.WriteLine($"Kira created: {ToJsonString(kira)}"); var keeperKeys = E2EeHelper.GenerateRsaKeyPair(); var kiraKeys = E2EeHelper.GenerateRsaKeyPair(); KeyStorage.SavePrivateKey("Keeper317", keeperKeys.privateKey); KeyStorage.SavePrivateKey("Ru_Kira", kiraKeys.privateKey); await db.Create("user_keys", new UserKeys { UserId = keeper.Id.ToString(), PublicKey = keeperKeys.publicKey, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }); await db.Create("user_keys", new UserKeys { UserId = kira.Id.ToString(), PublicKey = kiraKeys.publicKey, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }); Console.WriteLine("Public keys stored for both users."); var conversation = await db.Create("conversations", new Conversations { CreatedByUserId = keeper.Id.ToString(), CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow, Title = "Keeper317 + Ru_Kira", IsDirectMessage = true }); Console.WriteLine($"Conversation created: {ToJsonString(conversation)}"); await db.Create("conversation_members", new ConversationMembers { ConversationId = conversation.Id.ToString(), UserId = keeper.Id.ToString(), JoinedAt = DateTime.UtcNow }); await db.Create("conversation_members", new ConversationMembers { ConversationId = conversation.Id.ToString(), UserId = kira.Id.ToString(), JoinedAt = DateTime.UtcNow }); Console.WriteLine("Conversation members added."); var encrypted = E2EeHelper.EncryptForRecipient("hello from Keeper317", kiraKeys.publicKey); var savedMessage = await db.Create("messages", new Messages { ConversationId = conversation.Id.ToString(), SenderUserId = keeper.Id.ToString(), RecipientUserId = kira.Id.ToString(), CipherText = encrypted.CipherText, Nonce = encrypted.Nonce, Tag = encrypted.Tag, EncryptedKey = encrypted.EncryptedKey, CreatedAt = DateTime.UtcNow }); Console.WriteLine($"Encrypted message saved: {ToJsonString(savedMessage)}"); var decrypted = E2EeHelper.DecryptForRecipient(encrypted, kiraKeys.privateKey); Console.WriteLine($"Decrypted for Ru_Kira: {decrypted}"); return; static string ToJsonString(object? o) { return JsonSerializer.Serialize(o, new JsonSerializerOptions { WriteIndented = true }); } static async Task CreateUserAsync(SurrealDbClient db, string username, string email, string rawPassword) { var now = DateTime.UtcNow; var user = new Users { Username = username, Email = email, CreatedAt = now, UpdatedAt = now, LastLogin = now, TwoFactorEnabled = false, EmailVerified = false, AccountStatus = (int)AccountStatuses.Active, OnlineStatus = (int)OnlineStatuses.Online, }; var created = await db.Create("users", user); var hasher = new PasswordHasher.PasswordHasher(); var passwordHash = hasher.HashPassword(created.Id.ToString() + rawPassword); var updated = await db.Merge(new PasswordHash { Id = created.Id, Password = passwordHash }); return updated; } public static class KeyStorage { public static void SavePrivateKey(string username, string privateKey) { Directory.CreateDirectory("keys"); File.WriteAllText(Path.Combine("keys", $"{username}.private.key"), privateKey); } public static string LoadPrivateKey(string username) { return File.ReadAllText(Path.Combine("keys", $"{username}.private.key")); } public static bool PrivateKeyExists(string username) { return File.Exists(Path.Combine("keys", $"{username}.private.key")); } } public class ResponsibilityMerge : Record { public bool Marketing { get; set; } } public class Group { public bool Marketing { get; set; } public int Count { get; set; } } public class Users : Record { public required string Username { get; set; } public string? Password { get; set; } public required string Email { get; set; } public required DateTime CreatedAt { get; set; } public required DateTime UpdatedAt { get; set; } public required DateTime LastLogin { get; set; } public bool TwoFactorEnabled { get; set; } public bool EmailVerified { get; set; } public required int AccountStatus { get; set; } public required int OnlineStatus { get; set; } } public class PasswordHash : Record { public string? Password { get; set; } } public class Sessions : Record { public required string UserId { get; set; } public required string TokenHash { get; set; } public required DateTime IssuedAt { get; set; } public required DateTime ExpiresAt { get; set; } public DateTime? LastUsedAt { get; set; } public bool Revoked { get; set; } public required string DeviceName { get; set; } public required string IpAddress { get; set; } public required string UserAgent { get; set; } } public class PasswordReset : Record { public required string UserId { get; set; } public required string TokenHash { get; set; } public required DateTime CreatedAt { get; set; } public required DateTime ExpiresAt { get; set; } public bool Revoked { get; set; } } public class Licenses : Record { public required string UserId { get; set; } public required int LicenseType { get; set; } public required int Status { get; set; } public required DateTime CreatedAt { get; set; } public required DateTime StartsAt { get; set; } public required DateTime UpdatedAt { get; set; } public required DateTime ExpiresAt { get; set; } } public class AuthAudits : Record { public required string UserId { get; set; } public required int EventType { get; set; } public bool Success { get; set; } public required string IpAddress { get; set; } public required string UserAgent { get; set; } public required string Details { get; set; } public required DateTime CreatedAt { get; set; } } public class UserKeys : Record { public required string UserId { get; set; } public required string PublicKey { get; set; } public required DateTime CreatedAt { get; set; } public required DateTime UpdatedAt { get; set; } } public class Conversations : Record { public required string CreatedByUserId { get; set; } public required DateTime CreatedAt { get; set; } public required DateTime UpdatedAt { get; set; } public string? Title { get; set; } public bool IsDirectMessage { get; set; } } public class ConversationMembers : Record { public required string ConversationId { get; set; } public required string UserId { get; set; } public required DateTime JoinedAt { get; set; } } public class Messages : Record { public required string ConversationId { get; set; } public required string SenderUserId { get; set; } public required string RecipientUserId { get; set; } public required string CipherText { get; set; } public required string Nonce { get; set; } public required string Tag { get; set; } public required string EncryptedKey { get; set; } public required DateTime CreatedAt { get; set; } } enum AccountStatuses { Active, Suspended, Banned, Deleted } enum OnlineStatuses { Online, Busy, DND, Invisible, Offline } enum LicenseStatuses { Active, Expired, Renewable, Revoked } enum LicenseType { Free, Basic, Advanced, Pro, Enterprise } enum LogEvents { LoginSuccess, LoginFailure, LogoutSuccess, LogoutFailure, PasswordResetSuccess, PasswordResetFailure, }