22from ui .password_window import PasswordWindow
33from logic .storage import save_account_data
44from logic .authentication import authenticate_account
5+ from core .requests import socks_monkey_patch , http_monkey_patch , undo_monkey_patching
6+ from logic .user import build_initial_user_data
57from core .crypto import generate_sign_keys
68from urllib .parse import urlparse
79import tkinter as tk
@@ -20,7 +22,6 @@ def __init__(self, master):
2022 self .configure (bg = "black" )
2123 self .resizable (False , False )
2224
23- # Server input
2425 self .label = tk .Label (self , text = "Enter server URL:" , fg = "white" , bg = "black" )
2526 self .label .pack (pady = (20 , 5 ))
2627
@@ -31,7 +32,6 @@ def __init__(self, master):
3132
3233 enhanced_entry (self .server_url , placeholder = "I.e. example.com ..." )
3334
34- # Use Proxy
3535 self .use_proxy_var = tk .IntVar ()
3636 self .proxy_check = tk .Checkbutton (
3737 self ,
@@ -46,18 +46,14 @@ def __init__(self, master):
4646 )
4747 self .proxy_check .pack (pady = (10 , 0 ), anchor = "center" )
4848
49- # Proxy Fields Frame (hidden initially)
5049 self .proxy_fields_frame = tk .Frame (self , bg = "black" )
5150
52- # Proxy row (type + address)
5351 self .proxy_row = tk .Frame (self .proxy_fields_frame , bg = "black" )
5452
55- self .proxy_type_var = tk .StringVar (value = "SOCKS5 " )
53+ self .proxy_type_var = tk .StringVar (value = "HTTP " )
5654 self .proxy_type_var .trace_add ("write" , self .update_auth_visibility )
5755
58- self .proxy_type_menu = tk .OptionMenu (
59- self .proxy_row , self .proxy_type_var , "HTTP" , "SOCKS4" , "SOCKS5"
60- )
56+ self .proxy_type_menu = tk .OptionMenu (self .proxy_row , self .proxy_type_var , "HTTP" , "SOCKS4" , "SOCKS5" )
6157 self .proxy_type_menu .config (bg = "gray15" , fg = "white" , highlightthickness = 0 , width = 7 )
6258 self .proxy_type_menu .pack (side = "left" , padx = (0 , 5 ))
6359
@@ -69,7 +65,6 @@ def __init__(self, master):
6965
7066 self .proxy_row .pack (pady = 5 )
7167
72- # Auth row (username + password)
7368 self .auth_frame = tk .Frame (self .proxy_fields_frame , bg = "black" )
7469
7570 self .proxy_user_entry = tk .Entry (
@@ -86,16 +81,15 @@ def __init__(self, master):
8681
8782 self .proxy_fields_frame .pack_forget ()
8883
89- # Status + Connect
9084 self .status_label = tk .Label (self , text = "" , fg = "red" , bg = "black" )
9185 self .status_label .pack (pady = 5 )
9286
9387 self .connect_button = tk .Button (self , text = "Connect" , command = self .on_connect , bg = "gray25" , fg = "white" )
9488 self .connect_button .pack (pady = 10 )
9589
96- # Shrink to fit default
90+ # Shrink to fit default, autosize.
9791 self .update_idletasks ()
98- self .geometry ("" ) # Autosize
92+ self .geometry ("" )
9993
10094 def toggle_proxy_fields (self ):
10195 if self .use_proxy_var .get ():
@@ -105,11 +99,11 @@ def toggle_proxy_fields(self):
10599 self .proxy_fields_frame .pack_forget ()
106100
107101 self .update_idletasks ()
108- self .geometry ("" ) # Resize window
102+ self .geometry ("" ) # Resize again
109103
110104 def update_auth_visibility (self , * args ):
111- proxy_type = self .proxy_type_var .get (). lower ()
112- if proxy_type in ["http " , "socks5 " ]:
105+ proxy_type = self .proxy_type_var .get ()
106+ if proxy_type in ["HTTP " , "SOCKS5 " ]:
113107 self .auth_frame .pack (pady = 5 )
114108 else :
115109 self .auth_frame .pack_forget ()
@@ -119,11 +113,14 @@ def update_auth_visibility(self, *args):
119113
120114
121115 def password_callback (self , password ):
122- # We save the password (if any) in the user data for ease of access to simplify development
123- self .user_data = {"server_url" : self .server_url_fixed , "password" : password , "contacts" : {}, "tmp" : {}, "proxy_info" : None }
116+ # We save the password (if any) in the user data tmp dict for ease of access across codebase (i.e. saving)
117+ self .user_data = build_initial_user_data ()
118+ self .user_data ["server_url" ] = self .server_url_fixed
119+ self .user_data ["tmp" ]["password" ] = password
120+
124121 proxy_info = self .get_proxy_info ()
125122 if proxy_info :
126- self .user_data ["proxy_info" : proxy_info ]
123+ self .user_data ["settings" ][ " proxy_info"] = proxy_info
127124
128125 private_key , public_key = generate_sign_keys ()
129126
@@ -137,6 +134,22 @@ def password_callback(self, password):
137134 self .connect_to_server ()
138135
139136 def connect_to_server (self ):
137+ if self .user_data ["settings" ]["proxy_info" ]:
138+ if self .user_data ["settings" ]["proxy_info" ]["type" ] in ["SOCKS5" , "SOCKS4" ]:
139+ try :
140+ import socks
141+ except ImportError :
142+ logger .error ("SOCKS proxy set and we could not find PySocks. WARNING before you install PySocks: PySocks is largely unmaintained. It's highly recommended you use proxychains instead" )
143+ self .status_label .config (text = "You need to install PySocks to enable SOCKS proxy support!" )
144+ return
145+
146+ socks_monkey_patch (self .user_data ["settings" ]["proxy_info" ])
147+ else :
148+ http_monkey_patch (self .user_data ["settings" ]["proxy_info" ])
149+ else :
150+ undo_monkey_patching ()
151+
152+
140153 try :
141154 self .user_data = authenticate_account (self .user_data )
142155 except ValueError as e :
@@ -145,31 +158,36 @@ def connect_to_server(self):
145158
146159 save_account_data (self .user_data , self .master .user_data_lock )
147160 self .destroy ()
148- self .master .ready_to_authenticate_callback (self .user_data ["password" ])
161+ self .master .ready_to_authenticate_callback (self .user_data ["tmp" ][ " password" ], already_authenticated = True )
149162
150163
151164 def get_proxy_info (self ):
152165 proxy_info = None
153166 if self .use_proxy_var .get ():
154- proxy_type = self .proxy_type_var .get ().lower ()
155- proxy_addr = self .proxy_addr_entry .get ().strip ()
167+ proxy_type = self .proxy_type_var .get ()
168+ proxy_addr = self .proxy_addr_entry .get ().strip ()
169+ username = self .proxy_user_entry .get ().strip ()
170+ password = self .proxy_pass_entry .get ().strip ()
171+
156172 if not proxy_addr or ':' not in proxy_addr :
157173 self .status_label .config (text = "Invalid proxy address." )
158174 return
159175 host , port = proxy_addr .split (':' , 1 )
160176
177+ try :
178+ port = int (port )
179+ except ValueError :
180+ self .status_label .config (text = "Invalid proxy address port!" )
181+ return
182+
161183 proxy_info = {
162184 "type" : proxy_type ,
163185 "host" : host ,
164- "port" : int (port )
186+ "port" : port ,
187+ "username" : username ,
188+ "password" : password
165189 }
166190
167- username = self .proxy_user_entry .get ().strip ()
168- password = self .proxy_pass_entry .get ().strip ()
169- if username and password :
170- proxy_info ["username" ] = username
171- proxy_info ["password" ] = password
172-
173191 if proxy_info :
174192 logger .info ("Using proxy: %s" , json .dumps (proxy_info , indent = 2 ))
175193 return proxy_info
@@ -207,4 +225,4 @@ def on_connect(self, event=None):
207225 PasswordWindow (self , self .password_callback )
208226 else :
209227 self .status_label .config (text = "" )
210- self .password_callback (self .user_data ["password" ])
228+ self .password_callback (self .user_data ["tmp" ][ " password" ])
0 commit comments