44import binascii # hex encoding
55import platform # check platform
66import subprocess # needed for mac device
7- from datetime import datetime , timedelta
7+ import qrcode
8+ from datetime import datetime , timezone , timedelta
89from discord_interactions import verify_key # used for signature verification
10+ from PIL import Image
11+
912
1013try :
1114 if os .name == 'nt' :
@@ -143,7 +146,7 @@ def upgrade(self, user, license):
143146 time .sleep (3 )
144147 os ._exit (1 )
145148
146- def login (self , user , password , hwid = None ):
149+ def login (self , user , password , code = None , hwid = None ):
147150 self .checkinit ()
148151 if hwid is None :
149152 hwid = others .get_hwid ()
@@ -155,8 +158,11 @@ def login(self, user, password, hwid=None):
155158 "hwid" : hwid ,
156159 "sessionid" : self .sessionid ,
157160 "name" : self .name ,
158- "ownerid" : self .ownerid
161+ "ownerid" : self .ownerid ,
159162 }
163+
164+ if code is not None :
165+ post_data ["code" ] = code
160166
161167 response = self .__do_request (post_data )
162168
@@ -170,7 +176,7 @@ def login(self, user, password, hwid=None):
170176 time .sleep (3 )
171177 os ._exit (1 )
172178
173- def license (self , key , hwid = None ):
179+ def license (self , key , code = None , hwid = None ):
174180 self .checkinit ()
175181 if hwid is None :
176182 hwid = others .get_hwid ()
@@ -183,6 +189,9 @@ def license(self, key, hwid=None):
183189 "name" : self .name ,
184190 "ownerid" : self .ownerid
185191 }
192+
193+ if code is not None :
194+ post_data ["code" ] = code
186195
187196 response = self .__do_request (post_data )
188197
@@ -507,15 +516,87 @@ def logout(self):
507516 else :
508517 print (json ["message" ])
509518 time .sleep (3 )
510- os ._exit (1 )
519+ os ._exit (1 )
520+
521+ def enable2fa (self , code = None ):
522+ self .checkinit ()
523+
524+ post_data = {
525+ "type" : "2faenable" ,
526+ "sessionid" : self .sessionid ,
527+ "name" : self .name ,
528+ "ownerid" : self .ownerid ,
529+ "code" : code
530+ }
531+
532+ response = self .__do_request (post_data )
533+
534+ json = jsond .loads (response )
535+
536+ if json ["success" ]:
537+ if code is None :
538+ # First request: Display the 2FA secret code
539+ print (f"Your 2FA secret code is: { json ['2fa' ]['secret_code' ]} " )
540+ qr_code = json ['2fa' ]['QRCode' ]
541+ self .display_qr_code (qr_code )
542+ code_input = input ("Enter the 6 digit 2fa code to enable 2fa: " )
543+ self .enable2fa (code_input );
544+ else :
545+ # Second request: Confirm successful 2FA activation
546+ print ("2FA has been successfully enabled!" )
547+ time .sleep (3 )
548+ else :
549+ print (f"Error: { json ['message' ]} " )
550+ time .sleep (3 )
551+ os ._exit (1 )
552+
553+ def disable2fa (self , code = None ):
554+ self .checkinit ()
555+
556+ code = input ("Enter the 6 digit 2fa code to disable 2fa: " )
557+
558+ post_data = {
559+ "type" : "2fadisable" ,
560+ "sessionid" : self .sessionid ,
561+ "name" : self .name ,
562+ "ownerid" : self .ownerid ,
563+ "code" : code
564+ }
565+
566+ response = self .__do_request (post_data )
567+
568+ json = jsond .loads (response )
569+
570+ print (json ['message' ])
571+ time .sleep (3 )
572+
573+
574+ def display_qr_code (self , qr_code_url ):
575+ # Generate QR code image
576+ qr = qrcode .QRCode (
577+ version = 1 ,
578+ error_correction = qrcode .constants .ERROR_CORRECT_L ,
579+ box_size = 10 ,
580+ border = 4 ,
581+ )
582+
583+ # Add the QR code URL data
584+ qr .add_data (qr_code_url )
585+ qr .make (fit = True )
586+
587+ # Create an image from the QR code
588+ img = qr .make_image (fill = 'black' , back_color = 'white' )
589+
590+ # Display the QR code image
591+ img .show ()
511592
512593 def __do_request (self , post_data ):
513594 try :
514595 response = requests .post (
515- "https://keyauth.win/api/1.3/" , data = post_data , timeout = 10
596+ "https://keyauth.win/api/1.3/" , data = post_data , timeout = 10
516597 )
517598
518- if post_data ["type" ] == "log" or post_data ["type" ] == "file" :
599+ if post_data ["type" ] == "log" or post_data ["type" ] == "file" or post_data [ "type" ] == "2faenable" or post_data [ "type" ] == "2fadisable" :
519600 return response .text
520601
521602 # Get the signature and timestamp from the headers
@@ -527,8 +608,12 @@ def __do_request(self, post_data):
527608 time .sleep (3 )
528609 os ._exit (1 )
529610
530- server_time = datetime .utcfromtimestamp (int (timestamp ))
531- current_time = datetime .utcnow ()
611+ server_time = datetime .fromtimestamp (int (timestamp ), timezone .utc )
612+ current_time = datetime .now (timezone .utc )
613+
614+ #print(f"Server Timestamp (UTC seconds): {timestamp}")
615+ #print(f"Server Time (UTC seconds): {server_time.timestamp()}")
616+ #print(f"Current Time (UTC seconds): {current_time.timestamp()}")
532617
533618 buffer_seconds = 5
534619 time_difference = current_time - server_time
@@ -538,31 +623,17 @@ def __do_request(self, post_data):
538623 time .sleep (3 )
539624 os ._exit (1 )
540625
541- # Proceed with creating debug folders and logging
542- if not os .path .exists ("C:\\ ProgramData\\ KeyAuth" ):
543- os .makedirs ("C:\\ ProgramData\\ KeyAuth\\ Debug" )
544-
545- exe_name = os .path .basename (__file__ )
546- log_dir = f"C:\\ ProgramData\\ KeyAuth\\ Debug\\ { exe_name } "
547- if not os .path .exists (log_dir ):
548- os .makedirs (log_dir )
549-
550- with open (f"{ log_dir } \\ log.txt" , "a" ) as log_file :
551- if len (response .text ) <= 200 :
552- execution_time = time .strftime ("%I:%M %p | %m/%d/%Y" )
553- log_file .write (f"\n { execution_time } | { post_data ['type' ]} \n Response: { response .text } " )
554-
555626 if not verify_key (response .text .encode ('utf-8' ), signature , timestamp , '5586b4bc69c7a4b487e4563a4cd96afd39140f919bd31cea7d1c6a1e8439422b' ):
556627 print ("Signature checksum failed. Request was tampered with or session ended most likely." )
557- print ("Response: " + response .text )
558628 time .sleep (3 )
559629 os ._exit (1 )
560630
561631 return response .text
562632
563- except requests .exceptions .Timeout :
633+ except requests .exceptions .Timeout :
564634 print ("Request timed out. Server is probably down/slow at the moment" )
565-
635+
636+
566637 class application_data_class :
567638 numUsers = numKeys = app_ver = customer_panel = onlineUsers = ""
568639
0 commit comments