@@ -55,23 +55,60 @@ def dashboard():
5555
5656 # ===== API Routes =====
5757
58+ @app .route ('/api/domains' , methods = ['GET' ])
59+ @login_required
60+ def get_user_domains ():
61+ """Get all domains for the current user"""
62+ try :
63+ domains = current_user .get_domains ()
64+ return jsonify ({
65+ 'success' : True ,
66+ 'domains' : domains
67+ })
68+ except Exception as e :
69+ print (f"Error in /api/domains: { str (e )} " )
70+ traceback .print_exc ()
71+ return jsonify ({
72+ 'error' : 'Failed to fetch domains' ,
73+ 'domains' : []
74+ }), 500
75+
5876 @app .route ('/api/email-accounts' , methods = ['GET' ])
5977 @login_required
6078 def get_email_accounts ():
61- """Get all email accounts for the configured domain"""
79+ """Get all email accounts for the specified domain"""
6280 if not current_user .has_da_config ():
6381 return jsonify ({
6482 'error' : 'DirectAdmin not configured' ,
6583 'accounts' : []
6684 }), 400
6785
6886 try :
87+ # Get domain from query parameter or use first domain
88+ domain = request .args .get ('domain' )
89+ if not domain :
90+ domain = current_user .get_first_domain ()
91+
92+ if not domain :
93+ return jsonify ({
94+ 'error' : 'No domain specified' ,
95+ 'accounts' : []
96+ }), 400
97+
98+ # Verify user has access to this domain
99+ user_domains = current_user .get_domains ()
100+ if domain not in user_domains :
101+ return jsonify ({
102+ 'error' : 'Access denied to domain' ,
103+ 'accounts' : []
104+ }), 403
105+
69106 # Create API instance
70107 api = DirectAdminAPI (
71108 current_user .da_server ,
72109 current_user .da_username ,
73110 current_user .get_da_password (),
74- current_user . da_domain
111+ domain
75112 )
76113
77114 # Get email accounts
@@ -81,11 +118,12 @@ def get_email_accounts():
81118 if not isinstance (accounts , list ):
82119 accounts = []
83120
84- print (f"API returning { len (accounts )} email accounts" )
121+ print (f"API returning { len (accounts )} email accounts for domain { domain } " )
85122
86123 return jsonify ({
87124 'success' : True ,
88- 'accounts' : accounts
125+ 'accounts' : accounts ,
126+ 'domain' : domain
89127 })
90128
91129 except Exception as e :
@@ -99,20 +137,39 @@ def get_email_accounts():
99137 @app .route ('/api/forwarders' , methods = ['GET' ])
100138 @login_required
101139 def get_forwarders ():
102- """Get all email forwarders"""
140+ """Get all email forwarders for the specified domain """
103141 if not current_user .has_da_config ():
104142 return jsonify ({
105143 'error' : 'DirectAdmin not configured' ,
106144 'forwarders' : []
107145 }), 400
108146
109147 try :
148+ # Get domain from query parameter or use first domain
149+ domain = request .args .get ('domain' )
150+ if not domain :
151+ domain = current_user .get_first_domain ()
152+
153+ if not domain :
154+ return jsonify ({
155+ 'error' : 'No domain specified' ,
156+ 'forwarders' : []
157+ }), 400
158+
159+ # Verify user has access to this domain
160+ user_domains = current_user .get_domains ()
161+ if domain not in user_domains :
162+ return jsonify ({
163+ 'error' : 'Access denied to domain' ,
164+ 'forwarders' : []
165+ }), 403
166+
110167 # Create API instance
111168 api = DirectAdminAPI (
112169 current_user .da_server ,
113170 current_user .da_username ,
114171 current_user .get_da_password (),
115- current_user . da_domain
172+ domain
116173 )
117174
118175 # Get forwarders
@@ -122,11 +179,12 @@ def get_forwarders():
122179 if not isinstance (forwarders , list ):
123180 forwarders = []
124181
125- print (f"API returning { len (forwarders )} forwarders" )
182+ print (f"API returning { len (forwarders )} forwarders for domain { domain } " )
126183
127184 return jsonify ({
128185 'success' : True ,
129- 'forwarders' : forwarders
186+ 'forwarders' : forwarders ,
187+ 'domain' : domain
130188 })
131189
132190 except Exception as e :
@@ -152,6 +210,7 @@ def create_forwarder():
152210
153211 address = data .get ('address' , '' ).strip ()
154212 destination = data .get ('destination' , '' ).strip ()
213+ domain = data .get ('domain' , '' ).strip ()
155214
156215 # Validate inputs
157216 if not address :
@@ -160,12 +219,24 @@ def create_forwarder():
160219 if not destination :
161220 return jsonify ({'error' : 'Destination email is required' }), 400
162221
222+ # Get domain or use first domain
223+ if not domain :
224+ domain = current_user .get_first_domain ()
225+
226+ if not domain :
227+ return jsonify ({'error' : 'No domain specified' }), 400
228+
229+ # Verify user has access to this domain
230+ user_domains = current_user .get_domains ()
231+ if domain not in user_domains :
232+ return jsonify ({'error' : 'Access denied to domain' }), 403
233+
163234 # Create API instance
164235 api = DirectAdminAPI (
165236 current_user .da_server ,
166237 current_user .da_username ,
167238 current_user .get_da_password (),
168- current_user . da_domain
239+ domain
169240 )
170241
171242 # Create the forwarder
@@ -174,7 +245,8 @@ def create_forwarder():
174245 if success :
175246 return jsonify ({
176247 'success' : True ,
177- 'message' : message
248+ 'message' : message ,
249+ 'domain' : domain
178250 })
179251 else :
180252 return jsonify ({
@@ -202,16 +274,31 @@ def delete_forwarder():
202274 return jsonify ({'error' : 'No data provided' }), 400
203275
204276 address = data .get ('address' , '' ).strip ()
277+ domain = data .get ('domain' , '' ).strip ()
205278
206279 if not address :
207280 return jsonify ({'error' : 'Email address is required' }), 400
208281
282+ # Extract domain from address if not provided
283+ if not domain and '@' in address :
284+ domain = address .split ('@' )[1 ]
285+ elif not domain :
286+ domain = current_user .get_first_domain ()
287+
288+ if not domain :
289+ return jsonify ({'error' : 'No domain specified' }), 400
290+
291+ # Verify user has access to this domain
292+ user_domains = current_user .get_domains ()
293+ if domain not in user_domains :
294+ return jsonify ({'error' : 'Access denied to domain' }), 403
295+
209296 # Create API instance
210297 api = DirectAdminAPI (
211298 current_user .da_server ,
212299 current_user .da_username ,
213300 current_user .get_da_password (),
214- current_user . da_domain
301+ domain
215302 )
216303
217304 # Delete the forwarder
@@ -220,7 +307,8 @@ def delete_forwarder():
220307 if success :
221308 return jsonify ({
222309 'success' : True ,
223- 'message' : message
310+ 'message' : message ,
311+ 'domain' : domain
224312 })
225313 else :
226314 return jsonify ({
@@ -271,34 +359,7 @@ def handle_exception(error):
271359
272360 # ===== Database Initialization =====
273361
274- # Ensure DB initialization only once (important with multi-worker if --preload not used)
275- if not app .config .get ('_DB_INITIALIZED' , False ):
276- with app .app_context ():
277- print (f"Initializing database at URI: { app .config ['SQLALCHEMY_DATABASE_URI' ]} " )
278- db .create_all ()
279-
280- # Create default admin user only if no administrators exist
281- admin_count = User .query .filter_by (is_admin = True ).count ()
282- if admin_count == 0 :
283- # No administrators exist, create default admin user
284- admin_user = User (username = 'admin' , is_admin = True )
285- admin_user .set_password ('changeme' ) # Default password
286- db .session .add (admin_user )
287- try :
288- db .session .commit ()
289- print ("=" * 50 )
290- print ("Default admin user created!" )
291- print ("Username: admin" )
292- print ("Password: changeme" )
293- print ("PLEASE CHANGE THIS PASSWORD IMMEDIATELY!" )
294- print ("=" * 50 )
295- except Exception as e :
296- print (f"Error creating admin user: { e } " )
297- db .session .rollback ()
298- else :
299- print (f"Found { admin_count } administrator(s) - skipping default admin creation" )
300-
301- app .config ['_DB_INITIALIZED' ] = True
362+ # Ensure DB initialization only once (important with multi-worker if --preload not used)\n if not app.config.get('_DB_INITIALIZED', False):\n with app.app_context():\n print(f\"Initializing database at URI: {app.config['SQLALCHEMY_DATABASE_URI']}\")\n db.create_all()\n\n # Migrate existing users from single domain to multi-domain\n print(\"Checking for users to migrate to multi-domain...\")\n users_to_migrate = User.query.filter(\n User.da_domain.isnot(None),\n ~User.domains.any()\n ).all()\n \n for user in users_to_migrate:\n print(f\"Migrating user {user.username} with domain {user.da_domain}\")\n success, message = user.add_domain(user.da_domain)\n if success:\n print(f\" ✓ Migrated {user.username}: {message}\")\n else:\n print(f\" ✗ Failed to migrate {user.username}: {message}\")\n \n if users_to_migrate:\n try:\n db.session.commit()\n print(f\"Successfully migrated {len(users_to_migrate)} users to multi-domain.\")\n except Exception as e:\n print(f\"Error during migration: {e}\")\n db.session.rollback()\n\n # Create default admin user only if no administrators exist\n admin_count = User.query.filter_by(is_admin=True).count()\n if admin_count == 0:\n # No administrators exist, create default admin user\n admin_user = User(username='admin', is_admin=True)\n admin_user.set_password('changeme') # Default password\n db.session.add(admin_user)\n try:\n db.session.commit()\n print(\"=\" * 50)\n print(\"Default admin user created!\")\n print(\"Username: admin\")\n print(\"Password: changeme\")\n print(\"PLEASE CHANGE THIS PASSWORD IMMEDIATELY!\")\n print(\"=\" * 50)\n except Exception as e:\n print(f\"Error creating admin user: {e}\")\n db.session.rollback()\n else:\n print(f\"Found {admin_count} administrator(s) - skipping default admin creation\")\n\n app.config['_DB_INITIALIZED'] = True
302363
303364 # ===== Additional App Configuration =====
304365
0 commit comments