Luski.Net/Luski.net/MainServer.Account.cs
JacobTech c3bb39b21b Better Storage.
The example library now has better storage for local information and cache.
2023-07-10 07:35:05 -04:00

159 lines
7.0 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Authentication;
using System.Text;
using System.Text.Json;
using System.Threading;
using JacobTechEncryption;
using JacobTechEncryption.Enums;
using Luski.net.Enums;
using Luski.net.JsonTypes;
using Luski.net.JsonTypes.WSS;
using Luski.net.Structures.Main;
using WebSocketSharp;
namespace Luski.net;
public partial class MainServer
{
public void Login(string Username, string Password, CancellationToken CancellationToken)
{
Both(Username, Password, CancellationToken);
}
public void CreateAccount(string Username, string Password, string Displayname, string PFP, CancellationToken CancellationToken)
{
Both(Username, Password, CancellationToken, Displayname, PFP);
}
private void Both(string Username, string Password, CancellationToken CancellationToken, string? Displayname = null, string? pfp = null)
{
if (!EncryptionHandler.Generating)
{
EncryptionHandler.GenerateKeys();
}
while (!EncryptionHandler.Generated) { }
login = true;
Login json;
List<KeyValuePair<string, string?>> heads = new()
{
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 < EncryptionHandler.PasswordVersion && lpv >= 0)
{
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", Displayname));
json = SendServer(
"CreateAccount",
pfp,
LoginContext.Default.Login,
CancellationToken,
heads.ToArray()).Result;
}
else
{
json = GetFromServer(
"Login",
LoginContext.Default.Login,
CancellationToken,
heads.ToArray()).Result;
}
if (json.Error is not null) throw new Exception($"Luski appears to be down at the current moment: {json.ErrorMessage}");
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)
{
ServerOut = new WebSocket($"wss://{Domain}/WSS/{ApiVersion}");
ServerOut.SslConfiguration.EnabledSslProtocols = SslProtocols.Tls13 | SslProtocols.Tls12;
ServerOut.OnMessage += DataFromServer;
ServerOut.WaitTime = new TimeSpan(0, 0, 5);
ServerOut.OnError += ServerOut_OnError;
ServerOut.Connect();
SendServer(new WSSLogin() { Token = json.Token! }, WSSLoginContext.Default.WSSLogin);
while (Token is null && Error is null)
{
}
if (Error is not null)
{
throw new Exception(Error);
}
if (Token is null) throw new Exception("Server did not send a token");
CanRequest = true;
long id = long.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(
Token.Split('.')[0]
)));
User = GetUser(id, MainSocketAppUserContext.Default.MainSocketAppUser,
CancellationToken)
.Result;
if (User is null || User.Error is not null)
{
string error = "User was null";
if (User is not null && User.Error is not null) error = $"{User.Error}: {User.ErrorMessage}";
throw new Exception($"Something went wrong getting your user infermation\n{error}");
}
Console.WriteLine("User got");
Console.WriteLine("Insert");
_ = UpdateStatus(UserStatus.Online, CancellationToken);
Console.WriteLine("stat");
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);
if (offlinedata is not null && offlinedata.Error is null && offlinedata.Data is not null && offlinedata.Data.Length > 0)
{
foreach (string keyex in offlinedata.Data)
{
Console.WriteLine(keyex);
KeyExchange? okd = JsonSerializer.Deserialize<KeyExchange>(keyex);
Console.WriteLine(okd);
if (okd is not null && !string.IsNullOrEmpty(okd.key))
{
Console.WriteLine(okd.channel);
Console.WriteLine(okd.key);
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", 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(EncryptionHandler.OfflinePublicKey)).Result;
//_ = User.Channels;
foreach (var ch in chans)
{
_ = ch.Members;
}
EncryptionHandler.OfflinePublicKey = null;
EncryptionHandler.OfflinePrivateKey = null;
}
else throw new Exception(json?.ErrorMessage);
}
}