diff --git a/Luski.net/API.cs b/Luski.net/API.cs index c9bd04d..5934520 100644 --- a/Luski.net/API.cs +++ b/Luski.net/API.cs @@ -16,12 +16,8 @@ public class API { IEnumerable isl = InternalServers.Where(a => (a.Domain == Domain && a.ApiVersion == Version)); if (isl.Any()) return isl.First(); - PublicServer s = new() + PublicServer s = new(Domain, Version) { - Domain = Domain, - ApiVersion = Version, - Storage = new(Domain), - EncryptionHandler = new(Domain), ServerType = ServerType.Public }; InternalServers.Add(s); @@ -30,12 +26,8 @@ public class API public MainServer GetMainServer(string Domain, string Version = "v1") { - MainServer = new() + MainServer = new(Domain, Version) { - Domain = Domain, - ApiVersion = Version, - Storage = new(Domain), - EncryptionHandler = new(Domain), ServerType = ServerType.Main }; return MainServer; diff --git a/Luski.net/MainServer.Incoming.cs b/Luski.net/MainServer.Incoming.cs index db82b06..457df1a 100644 --- a/Luski.net/MainServer.Incoming.cs +++ b/Luski.net/MainServer.Incoming.cs @@ -47,8 +47,7 @@ public partial class MainServer MainSocketMessage? m = JsonSerializer.Deserialize(e.Data); if (m is not null) { - m.decrypt(Storage.GetResourceKey(StorageDirectory.ChannelKeys, m.ChannelID.ToString(), - EncryptionHandler.Hash), CancellationToken.None); + m.decrypt(EncryptionHandler.GetChannelKey(m.ChannelID), CancellationToken.None); _ = MessageReceived.Invoke(m); } } @@ -97,15 +96,12 @@ public partial class MainServer KeyExchange? KE = JsonSerializer.Deserialize(e.Data); if (KE is not null) { - Storage.SetResourceKey( - StorageDirectory.ChannelKeys, - KE.channel.ToString(), - EncryptionHandler.Hash, + EncryptionHandler.SetChannelKey( + KE.channel, Encoding.UTF8.GetString( - Encryption.RSA.Decrypt( - Convert.FromBase64String(KE.key), - EncryptionHandler.myPrivateKey - ) + Encryption.RSA.Decrypt( + Convert.FromBase64String(KE.key), + EncryptionHandler.myPrivateKey) ) ); } diff --git a/Luski.net/MainServer.cs b/Luski.net/MainServer.cs index 2076b42..979bc85 100644 --- a/Luski.net/MainServer.cs +++ b/Luski.net/MainServer.cs @@ -1,12 +1,16 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; +using System.Text; using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; +using JacobTechEncryption; using Luski.net.Enums; using Luski.net.Enums.Main; using Luski.net.Interfaces; +using Luski.net.JsonTypes; using Luski.net.JsonTypes.BaseTypes; using Luski.net.JsonTypes.HTTP; using Luski.net.Structures.Main; @@ -16,8 +20,76 @@ namespace Luski.net; public partial class MainServer : Server { + internal MainServer(string Domain, string API_Version): + base(Domain, API_Version) + { + } + public MainSocketAppUser User { get; internal set; } = default!; + public async Task SendFriendResult(long user, bool answer, CancellationToken CancellationToken) + { + FriendRequestResult json = await SendServer("FriendRequestResult", + new FriendRequestResultOut() + { + Id = user, + Result = answer + }, + FriendRequestResultOutContext.Default.FriendRequestResultOut, + FriendRequestResultContext.Default.FriendRequestResult, + CancellationToken); + + if (json is not null && json.Error is null && json.ErrorMessage is null && answer && json.Channel is not null) + { + MainSocketDMChannel chan = await GetChannel((long)json.Channel, MainSocketDMChannelContext.Default.MainSocketDMChannel, CancellationToken); + _ = chan.StartKeyProcessAsync(CancellationToken); + chans.Add(chan); + } + else + { + throw new Exception(json?.Error.ToString()); + } + return GetUser(user, MainSocketRemoteUserContext.Default.MainSocketRemoteUser, CancellationToken).Result; + } + + public async Task SendFriendRequest(long code, CancellationToken CancellationToken) + { + string ccode = Convert.ToBase64String(Encryption.Hashing.SHA256(Encoding.Unicode.GetBytes(code.ToString()))); + FriendRequestResult? json = await SendServer("FriendRequest", new FriendRequest() { code = ccode}, FriendRequestContext.Default.FriendRequest, FriendRequestResultContext.Default.FriendRequestResult, CancellationToken); + + if (json.StatusCode != HttpStatusCode.Accepted) + { + if (json is not null && json.Error is not null) + { + switch ((ErrorCode)(int)json.Error) + { + case ErrorCode.InvalidToken: + throw new Exception("Your current token is no longer valid"); + case ErrorCode.ServerError: + throw new Exception($"Error from server: {json.ErrorMessage}"); + case ErrorCode.InvalidPostData: + throw new Exception("The post data dent to the server is not the correct format. This may be because you app is couropt or you are using the wron API version"); + case ErrorCode.Forbidden: + throw new Exception("You already have an outgoing request or the persone is not real"); + } + } + + if (json is not null && json.Channel is not null) + { + MainSocketDMChannel chan = await GetChannel((long)json.Channel, MainSocketDMChannelContext.Default.MainSocketDMChannel, CancellationToken); + _ = chan.StartKeyProcessAsync(CancellationToken); + chans.Add(chan); + } + } + + MainSocketRemoteUser b = await GetUser(code, MainSocketRemoteUserContext.Default.MainSocketRemoteUser, CancellationToken); + if (json.Channel is not null) + b.FriendStatus = FriendStatus.Friends; + else + b.FriendStatus = FriendStatus.PendingOut; + return b; + } + public async Task GetChannel(long Channel, CancellationToken CancellationToken) where TChannel : MainSocketChannel, new() { TChannel Return = new(); diff --git a/Luski.net/PublicServer.cs b/Luski.net/PublicServer.cs index 63bbd3e..f23f971 100644 --- a/Luski.net/PublicServer.cs +++ b/Luski.net/PublicServer.cs @@ -2,5 +2,8 @@ namespace Luski.net; public class PublicServer : Server { - + internal PublicServer(string Domain, string API_Version): + base(Domain, API_Version) + { + } } \ No newline at end of file diff --git a/Luski.net/Server.Globals.cs b/Luski.net/Server.Globals.cs index 120898e..df5b3f1 100644 --- a/Luski.net/Server.Globals.cs +++ b/Luski.net/Server.Globals.cs @@ -14,8 +14,8 @@ namespace Luski.net; public partial class Server { public ServerType ServerType { get; internal set; } = ServerType.Public; - public string Domain { get; internal set; } = default!; - public string ApiVersion { get; internal set; } = "v1"; + public string Domain { get; } = default!; + public string ApiVersion { get; } = "v1"; internal WebSocket? ServerOut; internal string? Token = null, Error = null, gen = null; internal bool CanRequest = false, login = false; diff --git a/Luski.net/Server.cs b/Luski.net/Server.cs index 7dfbbde..4aad3bc 100644 --- a/Luski.net/Server.cs +++ b/Luski.net/Server.cs @@ -17,12 +17,16 @@ namespace Luski.net; public partial class Server { - internal Server() + internal Server(string Domain, string API_Version) { + this.Domain = Domain; + this.ApiVersion = API_Version; + Storage = new(Domain); + EncryptionHandler = new(Domain, API_Version, Storage); } - public ServerEncryption EncryptionHandler { get; internal set; } = null!; - public ServerStorage Storage { get; internal set; } = null!; + public ServerEncryption EncryptionHandler { get; } + public ServerStorage Storage { get; } public async Task GetAvatar(CancellationToken CancellationToken) { diff --git a/Luski.net/ServerEncryption.cs b/Luski.net/ServerEncryption.cs index ef7b8e2..057b698 100644 --- a/Luski.net/ServerEncryption.cs +++ b/Luski.net/ServerEncryption.cs @@ -1,6 +1,7 @@ using System; using System.Security.Cryptography; using JacobTechEncryption; +using Luski.net.Enums; namespace Luski.net; @@ -9,10 +10,23 @@ public class ServerEncryption internal bool Generating, Generated; internal string ServerPublicKey = "", MyPublicKey = "", myPrivateKey = "", OfflinePrivateKey = "", OfflinePublicKey = ""; internal byte[] Hash = default!; - internal ServerEncryption(string Domain) + internal ServerEncryption(string Domain, string API_Version, ServerStorage Storage) { + this.Storage = Storage; //TODO Get server p key } + + public string GetChannelKey(long Channel) + { + return Storage.GetResourceKey(StorageDirectory.ChannelKeys, Channel.ToString(), Hash); + } + + public void SetChannelKey(long Channel, string Key) + { + Storage.SetResourceKey(StorageDirectory.ChannelKeys, Channel.ToString(), Hash, Key); + } + + private ServerStorage Storage { get; } internal int PasswordVersion = 0; internal byte[] LocalPasswordEncrypt(byte[] Password) => LocalPasswordEncrypt(Password, PasswordVersion); diff --git a/Luski.net/Structures/Main/MainSocketChannel.cs b/Luski.net/Structures/Main/MainSocketChannel.cs index 050c19c..cc67919 100755 --- a/Luski.net/Structures/Main/MainSocketChannel.cs +++ b/Luski.net/Structures/Main/MainSocketChannel.cs @@ -70,8 +70,7 @@ public class MainSocketChannel : IncomingHTTP } int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 50) * 2.0)); if (num == 0) num = 1; - string lkey = Server.Storage.GetResourceKey(StorageDirectory.ChannelKeys, Id.ToString(), - Server.EncryptionHandler.Hash); + string lkey = Server.EncryptionHandler.GetChannelKey(Id); Parallel.ForEach(Members, new ParallelOptions() { MaxDegreeOfParallelism = num diff --git a/Luski.net/Structures/Main/MainSocketTextChannel.cs b/Luski.net/Structures/Main/MainSocketTextChannel.cs index 3147f0c..a8cae22 100755 --- a/Luski.net/Structures/Main/MainSocketTextChannel.cs +++ b/Luski.net/Structures/Main/MainSocketTextChannel.cs @@ -55,9 +55,8 @@ public class MainSocketTextChannel : MainSocketChannel { int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 5) * 2.0)); if (num == 0) num = 1; - - string key = Server.Storage.GetResourceKey(StorageDirectory.ChannelKeys, Id.ToString(), - Server.EncryptionHandler.Hash); + + string key = Server.EncryptionHandler.GetChannelKey(Id); if (data is null) throw new Exception("Invalid data from server"); if (data.Messages is null) data.Messages = Array.Empty(); Parallel.ForEach(data.Messages, new ParallelOptions() @@ -103,8 +102,7 @@ public class MainSocketTextChannel : MainSocketChannel { int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 5) * 2.0)); if (num == 0) num = 1; - string key = Server.Storage.GetResourceKey(StorageDirectory.ChannelKeys, Id.ToString(), - Server.EncryptionHandler.Hash); + string key = Server.EncryptionHandler.GetChannelKey(Id); if (data.Messages is null) data.Messages = Array.Empty(); Parallel.ForEach(data.Messages, new ParallelOptions() { @@ -139,8 +137,7 @@ public class MainSocketTextChannel : MainSocketChannel public async Task SendMessage(string Message, CancellationToken CancellationToken, params File?[] Files) { - string key = Server.Storage.GetResourceKey(StorageDirectory.ChannelKeys, Id.ToString(), - Server.EncryptionHandler.Hash); + string key = Server.EncryptionHandler.GetChannelKey(Id); JsonTypes.HTTP.Message m = new() { Context = Convert.ToBase64String(Encryption.RSA.Encrypt(Message, key, EncoderType.UTF8)),