2023-08-21 10:58:17 -04:00
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Security.Authentication ;
using System.Text ;
using System.Text.Json ;
using System.Threading ;
using System.Threading.Tasks ;
using JacobTechEncryption ;
using JacobTechEncryption.Enums ;
using Luski.net.Enums ;
using Luski.net.JsonTypes ;
using Luski.net.JsonTypes.BaseTypes ;
using Luski.net.JsonTypes.WSS ;
using Luski.net.Structures.Public ;
using WebSocketSharp ;
using DataType = Luski . net . Enums . Public . DataType ;
namespace Luski.net ;
public partial class PublicServer
{
public async Task < bool > Login ( string Username , string Password , CancellationToken CancellationToken )
{
return await Both ( Username , Password , CancellationToken ) ;
}
public async Task < bool > CreateAccount ( string Username , string Password , string Displayname , string PFP , CancellationToken CancellationToken )
{
return await Both ( Username , Password , CancellationToken , Displayname , PFP ) ;
}
internal async Task < bool > LoginViaToken ( string t )
{
CancellationToken CancellationToken = CancellationToken . None ;
if ( ! EncryptionHandler . Generating )
{
EncryptionHandler . GenerateKeys ( ) ;
}
while ( ! EncryptionHandler . Generated ) { }
login = true ;
Login json ;
List < KeyValuePair < string , string? > > heads = new ( )
{
new ( "key" , EncryptionHandler . MyPublicKey ) ,
new ( "token" , Convert . ToBase64String ( Encryption . RSA . Encrypt ( t , EncryptionHandler . ServerPublicKey , EncoderType . UTF16 ) ) ) ,
} ;
json = await GetFromServer (
"SocketAccount/AccessToken" ,
LoginContext . Default . Login ,
CancellationToken ,
heads . ToArray ( ) ) ;
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 ( wssurl ) ;
ServerOut . SslConfiguration . EnabledSslProtocols = SslProtocols . Tls13 | SslProtocols . Tls12 ;
ServerOut . OnMessage + = DataFromServer ;
ServerOut . EmitOnPing = true ;
ServerOut . WaitTime = new TimeSpan ( 0 , 0 , 5 ) ;
ServerOut . OnError + = ServerOut_OnError ;
ServerOut . Connect ( ) ;
SendServer ( DataType . Token , new WSSLogin ( ) { Token = json . Token ! } ) ;
while ( Token is null & & Error is null )
{
Thread . Sleep ( 500 ) ;
}
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 = await GetUser < SocketAppUser > ( id , CancellationToken ) ;
StorageInfoJSON data ;
if ( Storage . StorageID = = 0 )
{
EncryptionHandler . Hash = Storage . GenerateStorage ( ) ;
data = await SendServer ( "OfflineData/Info" ,
new StorageInfoJSON ( )
{
id = 0 ,
update = false ,
password = Convert . ToBase64String ( Encryption . AES . Encrypt ( EncryptionHandler . Hash , Storage . GetResourceBytes ( StorageDirectory . StorageInfo , "lpk" ) ) )
} ,
StorageInfoJSONContext . Default . StorageInfoJSON ,
StorageInfoJSONContext . Default . StorageInfoJSON , CancellationToken ,
new KeyValuePair < string , string? > ( "storage_id" , Storage . StorageID . ToString ( ) ) ) ;
Storage . setid ( data . id ) ;
}
else
{
data = await GetFromServer ( "OfflineData/Info" , StorageInfoJSONContext . Default . StorageInfoJSON , CancellationToken , new KeyValuePair < string , string? > ( "storage_id" , Storage . StorageID . ToString ( ) ) ) ;
}
if ( data . update )
{
EncryptionHandler . Hash = Storage . UpdateStorage ( Convert . FromBase64String ( data . password ) ) ;
_ = await SendServerPatch ( "OfflineData/Info" ,
new StorageInfoJSON ( )
{
id = 0 ,
update = false ,
password = Convert . ToBase64String ( Encryption . AES . Encrypt ( EncryptionHandler . Hash , Storage . GetResourceBytes ( StorageDirectory . StorageInfo , "lpk" ) ) )
} ,
StorageInfoJSONContext . Default . StorageInfoJSON ,
StorageInfoJSONContext . Default . StorageInfoJSON , CancellationToken ,
new KeyValuePair < string , string? > ( "storage_id" , Storage . StorageID . ToString ( ) ) ) ;
}
try
{
_ = EncryptionHandler . GetKey ( 0 ) ;
}
catch ( Exception e )
{
EncryptionHandler . SetKey ( 0 , new ( )
{
EncryptionType = EncryptionType . None ,
Key = string . Empty
} ) ;
}
_ = await UpdateStatus ( UserStatus . Online , CancellationToken ) ;
KeyValuePair < string , string? > stor = new ( "storage_id" , Storage . StorageID . ToString ( ) ) ;
OfflineData offlinedata = await GetFromServer ( "OfflineData" , OfflineDataContext . Default . OfflineData , CancellationToken , stor ) ;
if ( offlinedata is not null & & offlinedata . Error is null & & offlinedata . Data is not null & & offlinedata . Data . Length > 0 )
{
string pkey = Storage . GetResourceKeyRaw (
StorageDirectory . ServerKeys ,
"pkey" ,
EncryptionHandler . Hash
) ;
foreach ( string keyexx in offlinedata . Data )
{
string keyex = Encoding . UTF8 . GetString ( Convert . FromBase64String ( keyexx ) ) ;
KeyExchange ? okd = JsonSerializer . Deserialize < KeyExchange > ( keyex ) ;
if ( okd is not null & & ! string . IsNullOrEmpty ( okd . key ) )
{
Storage . SetResourceKey (
StorageDirectory . ChannelKeys ,
okd . channel . ToString ( ) ,
EncryptionHandler . Hash ,
Encoding . Unicode . GetString (
Encryption . RSA . Decrypt (
Convert . FromBase64String ( okd . key ) ,
pkey
)
)
) ;
}
}
}
Storage . SetResourceKey ( StorageDirectory . ServerKeys , "pkey" , EncryptionHandler . Hash , EncryptionHandler . OfflinePrivateKey ) ;
UserKeyGetRequest OfflineKeySetRequest = new ( )
{
key_data = Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( EncryptionHandler . OfflinePublicKey ) ) ,
encryption_type = EncryptionType . RSA
} ;
_ = await SendServer ( "Keys/SetOfflineKey" ,
OfflineKeySetRequest ,
UserKeyGetRequestContext . Default . UserKeyGetRequest ,
IncomingHTTPContext . Default . IncomingHTTP ,
CancellationToken . None ,
stor ) ;
EncryptionHandler . OfflinePublicKey = null ! ;
EncryptionHandler . OfflinePrivateKey = null ! ;
2023-10-01 13:12:27 -04:00
//API_Handler.IsAnyServerLoggedin = true;
2023-08-21 10:58:17 -04:00
return true ;
}
else
{
throw new Exception ( json ? . ErrorMessage ) ;
}
2023-10-01 13:12:27 -04:00
//API_Handler.IsAnyServerLoggedin = true;
2023-08-21 10:58:17 -04:00
return true ;
}
private async Task < bool > 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 . ServerPublicKey , EncoderType . UTF16 ) ) ) ,
new ( "password" , EncryptionHandler . RemotePasswordEncrypt ( Encryption . Generic . Encoders [ ( int ) EncoderType . UTF16 ] . 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 . Unicode . GetBytes ( Password ) , lpv ) ) ) ;
heads . Add ( new ( "old_version" , lpv . ToString ( ) ) ) ;
}
if ( pfp is not null )
{
heads . Add ( new ( "displayname" , Displayname ) ) ;
json = await SendServer (
"SocketAccount" ,
pfp ,
LoginContext . Default . Login ,
CancellationToken ,
heads . ToArray ( ) ) ;
}
else
{
json = await GetFromServer (
"SocketAccount" ,
LoginContext . Default . Login ,
CancellationToken ,
heads . ToArray ( ) ) ;
}
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 ( wssurl ) ;
ServerOut . SslConfiguration . EnabledSslProtocols = SslProtocols . Tls13 | SslProtocols . Tls12 ;
ServerOut . OnMessage + = DataFromServer ;
ServerOut . WaitTime = new TimeSpan ( 0 , 0 , 5 ) ;
ServerOut . EmitOnPing = true ;
ServerOut . OnError + = ServerOut_OnError ;
ServerOut . Connect ( ) ;
SendServer ( DataType . Token , new WSSLogin ( ) { Token = json . Token ! } ) ;
while ( Token is null & & Error is null )
{
Thread . Sleep ( 500 ) ;
}
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 = await GetUser < SocketAppUser > ( id , CancellationToken ) ;
StorageInfoJSON data ;
if ( Storage . StorageID = = 0 )
{
EncryptionHandler . Hash = Storage . GenerateStorage ( ) ;
data = await SendServer ( "OfflineData/Info" ,
new StorageInfoJSON ( )
{
id = 0 ,
update = false ,
password = Convert . ToBase64String ( Encryption . AES . Encrypt ( EncryptionHandler . Hash , Storage . GetResourceBytes ( StorageDirectory . StorageInfo , "lpk" ) ) )
} ,
StorageInfoJSONContext . Default . StorageInfoJSON ,
StorageInfoJSONContext . Default . StorageInfoJSON , CancellationToken ,
new KeyValuePair < string , string? > ( "storage_id" , Storage . StorageID . ToString ( ) ) ) ;
Storage . setid ( data . id ) ;
}
else
{
data = await GetFromServer ( "OfflineData/Info" , StorageInfoJSONContext . Default . StorageInfoJSON , CancellationToken , new KeyValuePair < string , string? > ( "storage_id" , Storage . StorageID . ToString ( ) ) ) ;
}
if ( data . update )
{
EncryptionHandler . Hash = Storage . UpdateStorage ( Convert . FromBase64String ( data . password ) ) ;
_ = await SendServerPatch ( "OfflineData/Info" ,
new StorageInfoJSON ( )
{
id = 0 ,
update = false ,
password = Convert . ToBase64String ( Encryption . AES . Encrypt ( EncryptionHandler . Hash , Storage . GetResourceBytes ( StorageDirectory . StorageInfo , "lpk" ) ) )
} ,
StorageInfoJSONContext . Default . StorageInfoJSON ,
StorageInfoJSONContext . Default . StorageInfoJSON , CancellationToken ,
new KeyValuePair < string , string? > ( "storage_id" , Storage . StorageID . ToString ( ) ) ) ;
}
try
{
_ = EncryptionHandler . GetKey ( 0 ) ;
}
catch ( Exception e )
{
EncryptionHandler . SetKey ( 0 , new ( )
{
EncryptionType = EncryptionType . None ,
Key = string . Empty
} ) ;
}
_ = await UpdateStatus ( UserStatus . Online , CancellationToken ) ;
//EncryptionHandler.Hash = EncryptionHandler.LocalPasswordEncrypt(Encoding.Unicode.GetBytes(Username.ToLower() + Password));
KeyValuePair < string , string? > stor = new ( "storage_id" , Storage . StorageID . ToString ( ) ) ;
OfflineData offlinedata = await GetFromServer ( "OfflineData" , OfflineDataContext . Default . OfflineData , CancellationToken , stor ) ;
if ( offlinedata is not null & & offlinedata . Error is null & & offlinedata . Data is not null & & offlinedata . Data . Length > 0 )
{
string pkey = Storage . GetResourceKeyRaw (
StorageDirectory . ServerKeys ,
"pkey" ,
EncryptionHandler . Hash
) ;
foreach ( string keyexx in offlinedata . Data )
{
string keyex = Encoding . UTF8 . GetString ( Convert . FromBase64String ( keyexx ) ) ;
KeyExchange ? okd = JsonSerializer . Deserialize < KeyExchange > ( keyex ) ;
if ( okd is not null & & ! string . IsNullOrEmpty ( okd . key ) )
{
Storage . SetResourceKey (
StorageDirectory . ChannelKeys ,
okd . channel . ToString ( ) ,
EncryptionHandler . Hash ,
Encoding . Unicode . GetString (
Encryption . RSA . Decrypt (
Convert . FromBase64String ( okd . key ) ,
pkey
)
)
) ;
}
}
}
System . IO . File . WriteAllText ( "LastPassVer.txt" , EncryptionHandler . PasswordVersion . ToString ( ) ) ;
Storage . SetResourceKey ( StorageDirectory . ServerKeys , "pkey" , EncryptionHandler . Hash , EncryptionHandler . OfflinePrivateKey ) ;
UserKeyGetRequest OfflineKeySetRequest = new ( )
{
key_data = Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( EncryptionHandler . OfflinePublicKey ) ) ,
encryption_type = EncryptionType . RSA
} ;
_ = await SendServer ( "Keys/SetOfflineKey" ,
OfflineKeySetRequest ,
UserKeyGetRequestContext . Default . UserKeyGetRequest ,
IncomingHTTPContext . Default . IncomingHTTP ,
CancellationToken . None ,
stor ) ;
// using HttpClient setkey = new();
// setkey.DefaultRequestHeaders.Add("token", Token);
// _ = await setkey.PostAsync($"{(Secure ? "https" : "http" )}://{Domain}/{ApiVersion}/Keys/SetOfflineKey", new StringContent(EncryptionHandler.OfflinePublicKey));
EncryptionHandler . OfflinePublicKey = null ! ;
EncryptionHandler . OfflinePrivateKey = null ! ;
2023-10-01 13:12:27 -04:00
//API_Handler.IsAnyServerLoggedin = true;
2023-08-21 10:58:17 -04:00
return true ;
}
else throw new Exception ( json ? . ErrorMessage ) ;
2023-10-01 13:12:27 -04:00
//API_Handler.IsAnyServerLoggedin = true;
2023-08-21 10:58:17 -04:00
return true ;
}
}