Better Storage.

The example library now has better storage for local information and cache.
This commit is contained in:
JacobTech 2023-07-10 07:35:05 -04:00
parent d8fbf281d0
commit c3bb39b21b
19 changed files with 353 additions and 199 deletions

View File

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Luski.net.Enums;
using Luski.net.Structures.Main;
using Luski.net.Structures.Public;
@ -19,6 +20,9 @@ public class API
{
Domain = Domain,
ApiVersion = Version,
Storage = new(Domain),
EncryptionHandler = new(Domain),
ServerType = ServerType.Public
};
InternalServers.Add(s);
return s;
@ -30,6 +34,9 @@ public class API
{
Domain = Domain,
ApiVersion = Version,
Storage = new(Domain),
EncryptionHandler = new(Domain),
ServerType = ServerType.Main
};
return MainServer;
}

View File

@ -1,51 +1,19 @@
using Luski.net.Enums;
using System;
/*using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using JacobTechEncryption;
namespace Luski.net
{
public static class ClientEncryption
{
internal static string? MyPublicKey;
internal static readonly UnicodeEncoding Encoder = new();
private static string? myPrivateKey;
internal static bool Generating = false;
internal static bool Generated = false;
private static string? _serverpublickey = null;
internal static string? ofkey = null;
internal static string? outofkey = null;
internal static string pw = "";
public static int NewKeySize = 4096;
public static void GenerateKeys()
{
if (!Generating)
{
Generating = true;
GenerateNewKeys(out MyPublicKey, out myPrivateKey);
GenerateNewKeys(out outofkey, out ofkey);
Generated = true;
}
}
public static void GenerateNewKeys(out string Public, out string Private)
{
using RSACryptoServiceProvider r = new(NewKeySize);
Private = r.ToXmlString(true);
Public = r.ToXmlString(false);
return;
}
public static class File
{
{/*
internal static void SetOfflineKey(string key)
{
MakeFile("Server.GetKeyFilePath", pw);
@ -54,11 +22,7 @@ namespace Luski.net
fileLayout.Save("Server.GetKeyFilePath", pw);
}
public static LuskiDataFile GetFile()
{
MakeFile("Server.GetKeyFilePath", pw);
return JsonSerializer.Deserialize<LuskiDataFile>(FileString("Server.GetKeyFilePath", pw))!;
}
internal static string? GetOfflineKey()
{
@ -66,6 +30,12 @@ namespace Luski.net
LuskiDataFile? fileLayout = JsonSerializer.Deserialize<LuskiDataFile>(FileString("Server.GetKeyFilePath", pw));
return fileLayout?.OfflineKey;
}
public static LuskiDataFile GetFile()
{
MakeFile("Server.GetKeyFilePath", pw);
return JsonSerializer.Deserialize<LuskiDataFile>(FileString("Server.GetKeyFilePath", pw))!;
}
private static string FileString(string path, string password)
{
@ -112,14 +82,14 @@ namespace Luski.net
public static class Channels
{
public static string GetKey(long channel)
private static string GetKey(long channel)
{
LuskiDataFile? fileLayout;
IEnumerable<ChannelLayout>? lis;
try
{
#pragma warning disable CS8603 // Possible null reference return.
if (channel == 0) return myPrivateKey;
// if (channel == 0) return myPrivateKey;
#pragma warning restore CS8603 // Possible null reference return.
MakeFile("Server.GetKeyFilePath", pw);
fileLayout = JsonSerializer.Deserialize<LuskiDataFile>(FileString("Server.GetKeyFilePath", pw));
@ -144,7 +114,7 @@ namespace Luski.net
try
{
#pragma warning disable CS8603 // Possible null reference return.
if (channel == 0) return myPrivateKey;
// if (channel == 0) return myPrivateKey;
#pragma warning restore CS8603 // Possible null reference return.
MakeFile("Server.GetKeyFilePathBr(branch.ToString())", pw);
fileLayout = JsonSerializer.Deserialize<LuskiDataFile>(FileString("", pw));
@ -273,8 +243,7 @@ namespace Luski.net
public string key { get; set; } = default!;
}
}
/*
public class AES
public class AES
{
public static string Encrypt(string path, string Password)
{
@ -301,12 +270,10 @@ namespace Luski.net
msEncrypt.Dispose();
return p;
/*
string p = Path.GetTempFileName();
string p = Path.GetTempFileName();
byte[] salt = new byte[100];
RNGCryptoServiceProvider provider = new();
provider.GetBytes(salt);
@ -378,27 +345,7 @@ namespace Luski.net
fsOut.Dispose();
}
}
*/
internal const int PasswordVersion = 0;
internal static byte[] LocalPasswordEncrypt(byte[] Password, int PasswordVersion = PasswordVersion)
{
return PasswordVersion switch
{
0 => SHA256.Create().ComputeHash(Password),
_ => throw new ArgumentException("The value provided was not accepted", nameof(PasswordVersion)),
};
}
internal static string RemotePasswordEncrypt(byte[] Password, int PasswordVersion = PasswordVersion)
{
return PasswordVersion switch
{
0 => Convert.ToBase64String(Encryption.RSA.Encrypt(LocalPasswordEncrypt(Password, PasswordVersion), MyPublicKey)),
_ => throw new ArgumentException("The value provided was not accepted", nameof(PasswordVersion)),
};
}
/*
public static byte[] Hash(byte[] data)
{
return SHA256.Create().ComputeHash(data);
@ -506,6 +453,6 @@ namespace Luski.net
}
}
return datasplitout;
}*/
}
}
}
}*/

View File

@ -1,6 +1,6 @@
namespace Luski.net.Enums;
public enum ServerCacheMode : byte
public enum CacheMode : byte
{
None,
Encrypted,

View File

@ -0,0 +1,12 @@
namespace Luski.net.Enums;
public enum StorageDirectory : byte
{
ServerInfo,
ServerAssets,
ChannelKeys,
ServerKeys,
Avatars,
ChannelIcons,
Messages
}

View File

@ -0,0 +1,24 @@
using System.Text.Json.Serialization;
using Luski.net.Enums;
namespace Luski.net.JsonTypes;
public class ServerStorageInfo
{
[JsonInclude]
[JsonPropertyName("cache_mode")]
public CacheMode CacheMode { get; set; } = CacheMode.Encrypted;
[JsonInclude]
[JsonPropertyName("prevent_deletion")]
public bool DontDelete { get; set; } = false;
}
[JsonSerializable(typeof(ServerStorageInfo))]
[JsonSourceGenerationOptions(
GenerationMode = JsonSourceGenerationMode.Default,
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
WriteIndented = true)]
internal partial class ServerStorageInfoContext : JsonSerializerContext
{
}

View File

@ -13,7 +13,7 @@
<RepositoryUrl>https://github.com/JacobTech-com/Luski.net</RepositoryUrl>
<IncludeSymbols>True</IncludeSymbols>
<FileVersion>1.0.0</FileVersion>
<Version>1.1.3-alpha24</Version>
<Version>1.1.3-alpha25</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -13,47 +13,46 @@ using Luski.net.Enums;
using Luski.net.JsonTypes;
using Luski.net.JsonTypes.WSS;
using Luski.net.Structures.Main;
using Luski.net.Structures.Public;
using WebSocketSharp;
namespace Luski.net;
public partial class MainServer
{
public void Login(string Email, string Password, System.Threading.CancellationToken CancellationToken)
public void Login(string Username, string Password, CancellationToken CancellationToken)
{
Both(Email, Password, CancellationToken);
Both(Username, Password, CancellationToken);
}
public void CreateAccount(string Email, string Password, string Username, string PFP, System.Threading.CancellationToken CancellationToken)
public void CreateAccount(string Username, string Password, string Displayname, string PFP, CancellationToken CancellationToken)
{
Both(Email, Password, CancellationToken, Username, PFP);
Both(Username, Password, CancellationToken, Displayname, PFP);
}
private void Both(string Email, string Password, System.Threading.CancellationToken CancellationToken, string? Username = null, string? pfp = null)
private void Both(string Username, string Password, CancellationToken CancellationToken, string? Displayname = null, string? pfp = null)
{
if (!ClientEncryption.Generating)
if (!EncryptionHandler.Generating)
{
ClientEncryption.GenerateKeys();
EncryptionHandler.GenerateKeys();
}
while (!ClientEncryption.Generated) { }
while (!EncryptionHandler.Generated) { }
login = true;
Login json;
List<KeyValuePair<string, string?>> heads = new()
{
new("key", ClientEncryption.MyPublicKey),
new("username", Convert.ToBase64String(Encryption.RSA.Encrypt(Email, ClientEncryption.MyPublicKey, EncoderType.UTF8))),
new("password", ClientEncryption.RemotePasswordEncrypt(Encoding.UTF8.GetBytes(Password)))
new("key", EncryptionHandler.MyPublicKey),
new("username", Convert.ToBase64String(Encryption.RSA.Encrypt(Username, EncryptionHandler.MyPublicKey, EncoderType.UTF8))),
new("password", EncryptionHandler.RemotePasswordEncrypt(Encoding.UTF8.GetBytes(Password)))
};
if (File.Exists("LastPassVer.txt") && int.TryParse(File.ReadAllText("LastPassVer.txt"), out int lpv) && lpv < ClientEncryption.PasswordVersion && lpv >= 0)
if (File.Exists("LastPassVer.txt") && int.TryParse(File.ReadAllText("LastPassVer.txt"), out int lpv) && lpv < EncryptionHandler.PasswordVersion && lpv >= 0)
{
heads.Add(new("old_password", ClientEncryption.RemotePasswordEncrypt(Encoding.UTF8.GetBytes(Password), lpv)));
heads.Add(new("old_password", EncryptionHandler.RemotePasswordEncrypt(Encoding.UTF8.GetBytes(Password), lpv)));
heads.Add(new("old_version", lpv.ToString()));
}
if (pfp is not null)
{
heads.Add(new("username", Username));
heads.Add(new("username", Displayname));
json = SendServer(
"CreateAccount",
pfp,
@ -70,7 +69,7 @@ public partial class MainServer
heads.ToArray()).Result;
}
if (json.Error is not null) throw new Exception($"Luski appears to be down at the current moment: {json.ErrorMessage}");
if (ClientEncryption.ofkey is null || ClientEncryption.outofkey is null) throw new Exception("Something went wrong generating the offline keys");
if (EncryptionHandler.OfflinePrivateKey is null || EncryptionHandler.OfflinePublicKey is null) throw new Exception("Something went wrong generating the offline keys");
login = false;
if (json is not null && json.Error is null)
{
@ -106,31 +105,9 @@ public partial class MainServer
}
Console.WriteLine("User got");
Console.WriteLine("Insert");
//User.Email = Email;
_ = UpdateStatus(UserStatus.Online, CancellationToken);
Console.WriteLine("stat");
try
{
ClientEncryption.pw = Email.ToLower() + Password;
_ = ClientEncryption.File.GetOfflineKey();
}
catch
{
try
{
ClientEncryption.pw = Email + Password;
var temp222 = ClientEncryption.File.LuskiDataFile.GetDefualtDataFile();
ClientEncryption.pw = Email.ToLower() + Password;
if (temp222 is not null) temp222.Save("key.lsk", ClientEncryption.pw);
}
catch
{
Token = null;
Error = null;
ServerOut.Close();
throw new Exception("The key file you have is getting the wrong pasword. Type your Email in the same way you creaated your account to fix this error.");
}
}
EncryptionHandler.Hash = EncryptionHandler.LocalPasswordEncrypt(Encoding.UTF8.GetBytes(Username.ToLower() + Password));
Console.WriteLine("req offline");
OfflineData offlinedata = GetFromServer("Keys/GetOfflineData", OfflineDataContext.Default.OfflineData, CancellationToken).Result;
if (offlinedata.Data is not null && offlinedata.Data.Any()) Console.WriteLine(offlinedata.Data);
@ -145,23 +122,37 @@ public partial class MainServer
{
Console.WriteLine(okd.channel);
Console.WriteLine(okd.key);
ClientEncryption.File.Channels.AddKey(okd.channel, Encoding.UTF8.GetString(Encryption.RSA.Decrypt(Convert.FromBase64String(okd.key), ClientEncryption.File.GetOfflineKey())));
Storage.SetResourceKey(
StorageDirectory.ChannelKeys,
okd.channel.ToString(),
EncryptionHandler.Hash,
Encoding.UTF8.GetString(
Encryption.RSA.Decrypt(
Convert.FromBase64String(okd.key),
Storage.GetResourceKey(
StorageDirectory.ServerKeys,
"pkey",
EncryptionHandler.Hash
)
)
)
);
}
}
}
Console.WriteLine("lpv");
System.IO.File.WriteAllText("LastPassVer.txt", ClientEncryption.PasswordVersion.ToString());
ClientEncryption.File.SetOfflineKey(ClientEncryption.ofkey);
System.IO.File.WriteAllText("LastPassVer.txt", EncryptionHandler.PasswordVersion.ToString());
Storage.SetResourceKey(StorageDirectory.ServerKeys, "pkey", EncryptionHandler.Hash, EncryptionHandler.OfflinePrivateKey);
using HttpClient setkey = new();
setkey.DefaultRequestHeaders.Add("token", Token);
_ = setkey.PostAsync($"https://{Domain}/{ApiVersion}/Keys/SetOfflineKey", new StringContent(ClientEncryption.outofkey)).Result;
_ = setkey.PostAsync($"https://{Domain}/{ApiVersion}/Keys/SetOfflineKey", new StringContent(EncryptionHandler.OfflinePublicKey)).Result;
//_ = User.Channels;
foreach (var ch in chans)
{
_ = ch.Members;
}
ClientEncryption.outofkey = null;
ClientEncryption.ofkey = null;
EncryptionHandler.OfflinePublicKey = null;
EncryptionHandler.OfflinePrivateKey = null;
}
else throw new Exception(json?.ErrorMessage);
}

View File

@ -1,4 +1,5 @@
using System;
using System.Text;
using System.Text.Json;
using System.Threading;
using JacobTechEncryption;
@ -46,7 +47,8 @@ public partial class MainServer
MainSocketMessage? m = JsonSerializer.Deserialize<MainSocketMessage>(e.Data);
if (m is not null)
{
m.decrypt(ClientEncryption.File.Channels.GetKey(m.ChannelID), CancellationToken.None);
m.decrypt(Storage.GetResourceKey(StorageDirectory.ChannelKeys, m.ChannelID.ToString(),
EncryptionHandler.Hash), CancellationToken.None);
_ = MessageReceived.Invoke(m);
}
}
@ -94,8 +96,19 @@ public partial class MainServer
{
KeyExchange? KE = JsonSerializer.Deserialize<KeyExchange>(e.Data);
if (KE is not null)
ClientEncryption.File.Channels.AddKey(KE.channel,
ClientEncryption.Encoder.GetString(Encryption.RSA.Decrypt(Convert.FromBase64String(KE.key), ClientEncryption.ofkey)));
{
Storage.SetResourceKey(
StorageDirectory.ChannelKeys,
KE.channel.ToString(),
EncryptionHandler.Hash,
Encoding.UTF8.GetString(
Encryption.RSA.Decrypt(
Convert.FromBase64String(KE.key),
EncryptionHandler.myPrivateKey
)
)
);
}
}
catch (Exception ex)
{

View File

@ -5,6 +5,7 @@ using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;
using Luski.net.Enums;
using Luski.net.Enums.Main;
using Luski.net.Interfaces;
using Luski.net.JsonTypes.BaseTypes;
using Luski.net.JsonTypes.HTTP;
@ -67,6 +68,8 @@ public partial class MainServer : Server
chans.Remove(p);
}
}
request.Server = this;
chans.Add(request);
return request;
}
@ -88,6 +91,9 @@ public partial class MainServer : Server
case MainSocketAppUser:
user = (GetUser(UserID, MainSocketAppUserContext.Default.MainSocketAppUser, CancellationToken).Result as Tuser)!;
break;
case MainSocketRemoteUser:
user = (GetUser(UserID, MainSocketRemoteUserContext.Default.MainSocketRemoteUser, CancellationToken).Result as Tuser)!;
break;
case MainSocketUserBase:
user = (GetUser(UserID, MainSocketUserBaseContext.Default.MainSocketUserBase, CancellationToken).Result as Tuser)!;
break;
@ -110,11 +116,16 @@ public partial class MainServer : Server
message = await GetFromServer("socketmessage",
MainSocketMessageContext.Default.MainSocketMessage,
CancellationToken,
new System.Collections.Generic.KeyValuePair<string, string?>("msg_id", id.ToString()));
new KeyValuePair<string, string?>("msg_id", id.ToString()));
break;
}
}
if (message is not null) return message;
if (message is not null)
{
message.Server = this;
return message;
}
throw new Exception("Server did not return a message");
}
@ -143,6 +154,16 @@ public partial class MainServer : Server
if (poeople.Count > 0 && poeople.Any(s => s.Id == UserId))
{
Tuser temp = poeople.Where(s => s is Tuser && s.Id == UserId).Cast<Tuser>().FirstOrDefault()!;
if (temp is MainSocketRemoteUser && (temp as MainSocketRemoteUser)!.Channel == null)
{
foreach (MainSocketDMChannel chan in chans.Where(s => s is MainSocketDMChannel).Cast<MainSocketDMChannel>())
{
if (chan.Type == ChannelType.DM && chan.Id != 0 && chan.MemberIdList is not null)
{
if (chan.MemberIdList.Any(s => s == UserId)) (temp as MainSocketRemoteUser)!.Channel = chan;
}
}
}
return temp;
}
while (true)
@ -165,6 +186,18 @@ public partial class MainServer : Server
poeople.Remove(p);
}
}
user.Server = this;
if (user is MainSocketRemoteUser && (user as MainSocketRemoteUser)!.Channel == null)
{
foreach (MainSocketDMChannel chan in chans.Where(s => s is MainSocketDMChannel).Cast<MainSocketDMChannel>())
{
if (chan.Type == ChannelType.DM && chan.Id != 0 && chan.MemberIdList is not null)
{
if (chan.MemberIdList.Any(s => s == UserId)) (user as MainSocketRemoteUser)!.Channel = chan;
}
}
}
poeople.Add(user);
return user;
}

View File

@ -15,50 +15,10 @@ public partial class Server
{
public ServerType ServerType { get; internal set; } = ServerType.Public;
public string Domain { get; internal set; } = default!;
public ServerCacheMode CacheMode { get; set; } = ServerCacheMode.None;
public string ApiVersion { get; internal set; } = "v1";
internal WebSocket? ServerOut;
internal string? Token = null, Error = null, gen = null;
internal bool CanRequest = false, login = false;
internal List<IUser> poeople = new();
public long UserID { get; internal set; } = 0;
internal List<MainSocketChannel> chans { get; set; } = new();
public string Cache
{
get
{
if (gen is null)
{
if (!Directory.Exists(JT)) Directory.CreateDirectory(JT);
string path = JT + "/Luski/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
path += "Data/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
path += UserID + "/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
path += "Cache/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
path += Path.GetRandomFileName() + "/";
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
gen = path;
}
if (!Directory.Exists($"{gen}/avatars")) Directory.CreateDirectory($"{gen}/avatars");
if (!Directory.Exists($"{gen}/channels")) Directory.CreateDirectory($"{gen}/channels");
return gen;
}
}
internal static string JT
{
get
{
string tmp = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "JacobTech");
if (OperatingSystem.IsLinux())
{
tmp = Path.Combine(Environment.GetEnvironmentVariable("HOME")!, ".config/");
tmp += "JacobTech";
}
return tmp;
}
}
}

View File

@ -10,12 +10,7 @@ using System.Threading;
using System.Threading.Tasks;
using Luski.net.Enums;
using Luski.net.Interfaces;
using Luski.net.JsonTypes;
using Luski.net.JsonTypes.BaseTypes;
using Luski.net.JsonTypes.HTTP;
using Luski.net.Structures;
using Luski.net.Structures.Main;
using Luski.net.Structures.Public;
using File = System.IO.File;
namespace Luski.net;
@ -23,16 +18,17 @@ namespace Luski.net;
public partial class Server
{
internal Server()
{ }
{
}
public ServerEncryption EncryptionHandler { get; internal set; } = null!;
public ServerStorage Storage { get; internal set; } = null!;
public async Task<byte[]> GetAvatar(CancellationToken CancellationToken)
{
if (Cache != null)
{
bool isc = File.Exists($"{Cache}/servers/{Domain}");
if (!isc) await GetFromServer($"socketserver/Avatar/", $"{Cache}/servers/{Domain}-{ApiVersion}", CancellationToken);
}
return File.ReadAllBytes($"{Cache}/servers/{Domain}");
bool isc = File.Exists(Storage.GetStorageDirectory(StorageDirectory.ServerAssets) + "Icon");
if (!isc) await GetFromServer($"socketserver/Avatar/", Storage.GetStorageDirectory(StorageDirectory.ServerAssets) + "Icon", CancellationToken);
return Storage.GetResourceBytes(StorageDirectory.ServerAssets, "Icon");
}
public void SendServer<Tvalue>(Tvalue Payload, JsonTypeInfo<Tvalue> jsonTypeInfo) where Tvalue : IncomingWSS

View File

@ -0,0 +1,56 @@
using System;
using System.Security.Cryptography;
using JacobTechEncryption;
namespace Luski.net;
public class ServerEncryption
{
internal bool Generating, Generated;
internal string ServerPublicKey = "", MyPublicKey = "", myPrivateKey = "", OfflinePrivateKey = "", OfflinePublicKey = "";
internal byte[] Hash = default!;
internal ServerEncryption(string Domain)
{
//TODO Get server p key
}
internal int PasswordVersion = 0;
internal byte[] LocalPasswordEncrypt(byte[] Password) => LocalPasswordEncrypt(Password, PasswordVersion);
internal string RemotePasswordEncrypt(byte[] Password) => RemotePasswordEncrypt(Password, PasswordVersion);
internal byte[] LocalPasswordEncrypt(byte[] Password, int PasswordVersion)
{
return PasswordVersion switch
{
0 => SHA256.Create().ComputeHash(Password),
_ => throw new ArgumentException("The value provided was not accepted", nameof(PasswordVersion)),
};
}
internal string RemotePasswordEncrypt(byte[] Password, int PasswordVersion)
{
return PasswordVersion switch
{
0 => Convert.ToBase64String(Encryption.RSA.Encrypt(LocalPasswordEncrypt(Password, PasswordVersion), ServerPublicKey)),
_ => throw new ArgumentException("The value provided was not accepted", nameof(PasswordVersion)),
};
}
public void GenerateKeys()
{
if (!Generating)
{
Generating = true;
GenerateNewKeys(out MyPublicKey, out myPrivateKey);
GenerateNewKeys(out OfflinePublicKey, out OfflinePrivateKey);
Generated = true;
}
}
public static void GenerateNewKeys(out string Public, out string Private, int KeySize = 4096)
{
using RSACryptoServiceProvider r = new(KeySize);
Private = r.ToXmlString(true);
Public = r.ToXmlString(false);
}
}

116
Luski.net/ServerStorage.cs Normal file
View File

@ -0,0 +1,116 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using JacobTechEncryption;
using Luski.net.Enums;
using Luski.net.JsonTypes;
namespace Luski.net;
public class ServerStorage
{
public static readonly string[] Directories = new[]
{
"Info",
"Assets",
"Channels/Keys",
"Keys",
"Avatars",
"Channels/Icons",
"Channels/Messages"
};
private static readonly int[] CantDelete = new[]
{
(int)StorageDirectory.ChannelKeys,
(int)StorageDirectory.ServerKeys
};
internal ServerStorage(string Domain)
{
if (!Directory.Exists(JT)) Directory.CreateDirectory(JT);
Location = JT + "/Luski/";
if (!Directory.Exists(Location)) Directory.CreateDirectory(Location);
Location += "Storage/";
if (!Directory.Exists(Location)) Directory.CreateDirectory(Location);
Location += "Servers/";
if (!Directory.Exists(Location)) Directory.CreateDirectory(Location);
Location += Domain+ "/";
if (!Directory.Exists(Location)) Directory.CreateDirectory(Location);
if (!File.Exists(Location + "storage.json")) File.WriteAllText(Location + "storage.json", JsonSerializer.Serialize(new ServerStorageInfo(),ServerStorageInfoContext.Default.ServerStorageInfo));
ServerStorageInfo info = JsonSerializer.Deserialize(File.ReadAllText(Location + "storage.json"),
ServerStorageInfoContext.Default.ServerStorageInfo)!;
CacheMode = info.CacheMode;
for (int i = 0; i < Directories.Length; i++)
{
string full = Location;
string[] spl = Directories[i].Split('/');
if (!info.DontDelete && !CantDelete.Contains(i))
{
try
{
if (Directory.Exists(full + spl[0])) Directory.Delete(full + spl[0], true);
}
catch
{
// ignored
}
}
foreach (string d in spl)
{
full += d + "/";
if (!Directory.Exists(full)) Directory.CreateDirectory(full);
}
}
}
public string Location { get; internal set; }
public string GetStorageDirectory(StorageDirectory Directory)
{
return Location + Directories[(byte)Directory] + "/";
}
public string GetResourceKey(StorageDirectory Directory, string Resource, string Key)
{
return Encoding.UTF8.GetString(Encryption.AES.Decrypt(GetResourceBytes(Directory, Resource), Key));
}
public string GetResourceKey(StorageDirectory Directory, string Resource, byte[] Key)
{
return Encoding.UTF8.GetString(Encryption.AES.Decrypt(GetResourceBytes(Directory, Resource), Encoding.UTF8.GetString(Key)));
}
public void SetResourceKey(StorageDirectory Directory, string Resource, string Key, string value)
{
File.WriteAllBytes(GetStorageDirectory(Directory) + Resource, Encryption.AES.Encrypt(Encoding.UTF8.GetBytes(value), Key));
}
public void SetResourceKey(StorageDirectory Directory, string Resource, byte[] Key, string value)
{
File.WriteAllBytes(GetStorageDirectory(Directory) + Resource, Encryption.AES.Encrypt(Encoding.UTF8.GetBytes(value), Encoding.UTF8.GetString(Key)));
}
public byte[] GetResourceBytes(StorageDirectory Directory, string Resource)
{
return File.ReadAllBytes(Location + Directories[(byte)Directory] + "/" + Resource);
}
public CacheMode CacheMode { get; internal set; }
internal static string JT
{
get
{
string tmp = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "JacobTech");
if (OperatingSystem.IsLinux())
{
tmp = Path.Combine(Environment.GetEnvironmentVariable("HOME")!, ".config/");
tmp += "JacobTech";
}
return tmp;
}
}
}

View File

@ -18,7 +18,7 @@ namespace Luski.net.Structures;
public class File : IncomingHTTP
{
public IServer Server { get; internal set; }
public MainServer Server { get; internal set; }
[JsonInclude]
[JsonPropertyName("name")]
public string Name { get; internal set; } = default!;
@ -35,6 +35,8 @@ public class File : IncomingHTTP
public async Task DownloadBytes(string Loc, long key, CancellationToken CancellationToken)
{
//TODO make better
//using HttpClient web = new();
//web.DefaultRequestHeaders.Add("token", Server.Token);
//web.DefaultRequestHeaders.Add("id", id.ToString());
@ -42,7 +44,7 @@ public class File : IncomingHTTP
string path = Path.GetTempFileName();
await Server.GetFromServer($"SocketMessage/GetFile/{Id}", path, CancellationToken);
string Key = (key == 0 ? ClientEncryption.MyPublicKey : ClientEncryption.File.Channels.GetKey(key))!;
string Key = (key == 0 ? Server.EncryptionHandler.MyPublicKey : "") ;// ClientEncryption.File.Channels.GetKey(key))!;
Encryption.AES.DecryptToFile(System.IO.File.ReadAllBytes(path), Key, Loc);
/*
if (request is not null && request.Error is not null)

View File

@ -70,7 +70,8 @@ public class MainSocketChannel : IncomingHTTP
}
int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 50) * 2.0));
if (num == 0) num = 1;
string? lkey = ClientEncryption.File.Channels.GetKey(Id);
string lkey = Server.Storage.GetResourceKey(StorageDirectory.ChannelKeys, Id.ToString(),
Server.EncryptionHandler.Hash);
Parallel.ForEach(Members, new ParallelOptions()
{
MaxDegreeOfParallelism = num
@ -95,7 +96,9 @@ public class MainSocketChannel : IncomingHTTP
}
internal Task StartKeyProcessAsync(CancellationToken CancellationToken)
{/*
{
//TODO code key exchange
/*
ClientEncryption.GenerateNewKeys(out string Public, out string Private);
Key = Public;
HttpResponseMessage b;

View File

@ -18,6 +18,7 @@ public class MainSocketRemoteUser : MainSocketUserBase
[JsonPropertyName("friend_status")]
[JsonInclude]
public FriendStatus FriendStatus { get; internal set; } = default!;
public MainSocketDMChannel Channel { get; internal set; }
internal MainSocketRemoteUser Clone()
{

View File

@ -27,12 +27,9 @@ public class MainSocketTextChannel : MainSocketChannel
if (Type == ChannelType.DM) return Members.First().GetAvatar(CancellationToken).Result;
else
{
if (Server.Cache != null)
{
bool isc = System.IO.File.Exists($"{Server.Cache}/channels/{Id}");
if (!isc) await Server.GetFromServer($"SocketChannel/GetPicture/{Id}", $"{Server.Cache}/channels/{Id}", CancellationToken);
}
return System.IO.File.ReadAllBytes($"{Server.Cache}/channels/{Id}");
bool isc = System.IO.File.Exists(Server.Storage.GetStorageDirectory(StorageDirectory.ChannelIcons) + Id.ToString());
if (!isc) await Server.GetFromServer($"SocketChannel/GetPicture/{Id}", Server.Storage.GetStorageDirectory(StorageDirectory.ChannelIcons) + Id.ToString(), CancellationToken);
return Server.Storage.GetResourceBytes(StorageDirectory.ChannelIcons, Id.ToString());
}
}
@ -59,7 +56,8 @@ public class MainSocketTextChannel : MainSocketChannel
int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 5) * 2.0));
if (num == 0) num = 1;
string? key = ClientEncryption.File.Channels.GetKey(Id);
string key = Server.Storage.GetResourceKey(StorageDirectory.ChannelKeys, Id.ToString(),
Server.EncryptionHandler.Hash);
if (data is null) throw new Exception("Invalid data from server");
if (data.Messages is null) data.Messages = Array.Empty<MainSocketMessage>();
Parallel.ForEach(data.Messages, new ParallelOptions()
@ -105,7 +103,8 @@ public class MainSocketTextChannel : MainSocketChannel
{
int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 5) * 2.0));
if (num == 0) num = 1;
string? key = ClientEncryption.File.Channels.GetKey(Id);
string key = Server.Storage.GetResourceKey(StorageDirectory.ChannelKeys, Id.ToString(),
Server.EncryptionHandler.Hash);
if (data.Messages is null) data.Messages = Array.Empty<MainSocketMessage>();
Parallel.ForEach(data.Messages, new ParallelOptions()
{
@ -140,8 +139,8 @@ public class MainSocketTextChannel : MainSocketChannel
public async Task<Task> SendMessage(string Message, CancellationToken CancellationToken, params File?[] Files)
{
string key = ClientEncryption.File.Channels.GetKey(Id);
if (Id == 0) key = "";//ClientEncryption.ServerPublicKey;
string key = Server.Storage.GetResourceKey(StorageDirectory.ChannelKeys, Id.ToString(),
Server.EncryptionHandler.Hash);
JsonTypes.HTTP.Message m = new()
{
Context = Convert.ToBase64String(Encryption.RSA.Encrypt(Message, key, EncoderType.UTF8)),

View File

@ -24,12 +24,9 @@ public class MainSocketUserBase : IncomingHTTP, IUser
public PictureType PictureType { get; internal set; } = default!;
public async Task<byte[]> GetAvatar(CancellationToken CancellationToken)
{
if (Server.Cache != null)
{
bool isc = System.IO.File.Exists($"{Server.Cache}/avatars/{Id}");
if (!isc) await Server.GetFromServer($"socketuserprofile/Avatar/{Id}", $"{Server.Cache}/avatars/{Id}", CancellationToken);
}
return System.IO.File.ReadAllBytes($"{Server.Cache}/avatars/{Id}");
bool isc = System.IO.File.Exists(Server.Storage.GetStorageDirectory(StorageDirectory.Avatars) + Id.ToString());
if (!isc) await Server.GetFromServer($"socketuserprofile/Avatar/{Id}", Server.Storage.GetStorageDirectory(StorageDirectory.Avatars) + Id.ToString(), CancellationToken);
return Server.Storage.GetResourceBytes(StorageDirectory.Avatars, Id.ToString());
}
public Task<long> GetUserKey(CancellationToken CancellationToken)

View File

@ -24,12 +24,9 @@ public class PublicSocketUserBase : IncomingHTTP, IUser
public PictureType PictureType { get; internal set; } = default!;
public async Task<byte[]> GetAvatar(CancellationToken CancellationToken)
{
if (Server.Cache != null)
{
bool isc = System.IO.File.Exists($"{Server.Cache}/avatars/{Id}");
if (!isc) await Server.GetFromServer($"socketuserprofile/Avatar/{Id}", $"{Server.Cache}/avatars/{Id}", CancellationToken);
}
return System.IO.File.ReadAllBytes($"{Server.Cache}/avatars/{Id}");
bool isc = System.IO.File.Exists(Server.Storage.GetStorageDirectory(StorageDirectory.Avatars) + Id.ToString());
if (!isc) await Server.GetFromServer($"socketuserprofile/Avatar/{Id}", Server.Storage.GetStorageDirectory(StorageDirectory.Avatars) + Id.ToString(), CancellationToken);
return Server.Storage.GetResourceBytes(StorageDirectory.Avatars, Id.ToString());
}
public Task<long> GetUserKey(CancellationToken CancellationToken)