diff --git a/routes/__pycache__/main.cpython-313.pyc b/routes/__pycache__/main.cpython-313.pyc index 26e8381..caa229e 100644 Binary files a/routes/__pycache__/main.cpython-313.pyc and b/routes/__pycache__/main.cpython-313.pyc differ diff --git a/routes/admin_api.py b/routes/admin_api.py index cce01af..25cb4d3 100644 --- a/routes/admin_api.py +++ b/routes/admin_api.py @@ -920,4 +920,239 @@ def save_git_connection(current_user): return jsonify({'message': 'Settings saved successfully'}) except Exception as e: - return jsonify({'error': str(e)}), 500 \ No newline at end of file + return jsonify({'error': str(e)}), 500 + +@admin_api.route('/create-proxy-host', methods=['POST']) +@csrf.exempt +@token_required +def create_proxy_host(current_user): + if not current_user.is_admin: + return jsonify({'error': 'Unauthorized'}), 403 + + data = request.get_json() + domains = data.get('domains') + scheme = data.get('scheme', 'http') + forward_ip = data.get('forward_ip') + forward_port = data.get('forward_port') + + if not domains or not forward_ip or not forward_port: + return jsonify({'error': 'Missing required fields'}), 400 + + try: + # Get NGINX settings + nginx_settings = KeyValueSettings.get_value('nginx_settings') + if not nginx_settings: + return jsonify({'error': 'NGINX settings not configured'}), 400 + + # First, get the JWT token + token_response = requests.post( + f"{nginx_settings['url'].rstrip('/')}/api/tokens", + json={ + 'identity': nginx_settings['username'], + 'secret': nginx_settings['password'] + }, + headers={'Content-Type': 'application/json'}, + timeout=5 + ) + + if token_response.status_code != 200: + return jsonify({'error': 'Failed to authenticate with NGINX Proxy Manager'}), 400 + + token_data = token_response.json() + token = token_data.get('token') + + if not token: + return jsonify({'error': 'No token received from NGINX Proxy Manager'}), 400 + + # Create the proxy host + proxy_host_data = { + 'domain_names': domains, + 'forward_scheme': scheme, + 'forward_host': forward_ip, + 'forward_port': int(forward_port), + 'ssl_forced': True, + 'caching_enabled': True, + 'block_exploits': True, + 'allow_websocket_upgrade': True, + 'http2_support': True, + 'hsts_enabled': True, + 'hsts_subdomains': True, + 'meta': { + 'letsencrypt_agree': True, + 'dns_challenge': False + } + } + + response = requests.post( + f"{nginx_settings['url'].rstrip('/')}/api/nginx/proxy-hosts", + json=proxy_host_data, + headers={ + 'Authorization': f'Bearer {token}', + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + timeout=5 + ) + + if response.status_code == 200: + return jsonify({ + 'message': 'Proxy host created successfully', + 'data': response.json() + }) + else: + error_data = response.json() + return jsonify({ + 'error': f'Failed to create proxy host: {error_data.get("message", "Unknown error")}' + }), 400 + + except Exception as e: + return jsonify({'error': str(e)}), 500 + +@admin_api.route('/create-ssl-certificate', methods=['POST']) +@csrf.exempt +@token_required +def create_ssl_certificate(current_user): + try: + data = request.get_json() + current_app.logger.info(f"Received request data: {data}") + + domains = data.get('domains') + proxy_host_id = data.get('proxy_host_id') + nginx_url = data.get('nginx_url') + + current_app.logger.info(f"Extracted data - domains: {domains}, proxy_host_id: {proxy_host_id}, nginx_url: {nginx_url}") + + if not all([domains, proxy_host_id, nginx_url]): + missing_fields = [] + if not domains: missing_fields.append('domains') + if not proxy_host_id: missing_fields.append('proxy_host_id') + if not nginx_url: missing_fields.append('nginx_url') + + current_app.logger.error(f"Missing required fields: {missing_fields}") + return jsonify({ + 'success': False, + 'error': f'Missing required fields: {", ".join(missing_fields)}' + }), 400 + + # Get NGINX settings + nginx_settings = KeyValueSettings.get_value('nginx_settings') + if not nginx_settings: + return jsonify({ + 'success': False, + 'error': 'NGINX settings not configured' + }), 400 + + # First, get the JWT token + token_response = requests.post( + f"{nginx_settings['url'].rstrip('/')}/api/tokens", + json={ + 'identity': nginx_settings['username'], + 'secret': nginx_settings['password'] + }, + headers={'Content-Type': 'application/json'}, + timeout=5 + ) + + if token_response.status_code != 200: + return jsonify({ + 'success': False, + 'error': 'Failed to authenticate with NGINX Proxy Manager' + }), 400 + + token_data = token_response.json() + token = token_data.get('token') + + if not token: + return jsonify({ + 'success': False, + 'error': 'No token received from NGINX Proxy Manager' + }), 400 + + # Create the SSL certificate + ssl_request_data = { + 'provider': 'letsencrypt', + 'domain_names': domains, + 'meta': { + 'letsencrypt_agree': True, + 'dns_challenge': False + } + } + current_app.logger.info(f"Making SSL certificate request to {nginx_url}/api/nginx/ssl with data: {ssl_request_data}") + + ssl_response = requests.post( + f"{nginx_url}/api/nginx/ssl", + headers={ + 'Authorization': f'Bearer {token}', + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + json=ssl_request_data + ) + + current_app.logger.info(f"SSL certificate response status: {ssl_response.status_code}") + current_app.logger.info(f"SSL certificate response headers: {dict(ssl_response.headers)}") + + if not ssl_response.ok: + error_text = ssl_response.text + current_app.logger.error(f"Failed to create SSL certificate: {error_text}") + return jsonify({ + 'success': False, + 'error': f'Failed to create SSL certificate: {error_text}' + }), ssl_response.status_code + + ssl_data = ssl_response.json() + current_app.logger.info(f"SSL certificate created successfully: {ssl_data}") + + # Get the certificate ID + cert_id = ssl_data.get('id') + if not cert_id: + current_app.logger.error("No certificate ID received in response") + return jsonify({ + 'success': False, + 'error': 'No certificate ID received' + }), 500 + + # Update the proxy host with the certificate + update_request_data = { + 'ssl_certificate_id': cert_id + } + current_app.logger.info(f"Updating proxy host {proxy_host_id} with data: {update_request_data}") + + update_response = requests.put( + f"{nginx_url}/api/nginx/proxy-hosts/{proxy_host_id}", + headers={ + 'Authorization': f'Bearer {token}', + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + json=update_request_data + ) + + current_app.logger.info(f"Update response status: {update_response.status_code}") + current_app.logger.info(f"Update response headers: {dict(update_response.headers)}") + + if not update_response.ok: + error_text = update_response.text + current_app.logger.error(f"Failed to update proxy host: {error_text}") + return jsonify({ + 'success': False, + 'error': f'Failed to update proxy host: {error_text}' + }), update_response.status_code + + update_data = update_response.json() + current_app.logger.info(f"Proxy host updated successfully: {update_data}") + + return jsonify({ + 'success': True, + 'data': { + 'certificate': ssl_data, + 'proxy_host': update_data + } + }) + + except Exception as e: + current_app.logger.error(f"Error in create_ssl_certificate: {str(e)}") + return jsonify({ + 'success': False, + 'error': str(e) + }), 500 \ No newline at end of file diff --git a/routes/main.py b/routes/main.py index 6f84a29..5ba8578 100644 --- a/routes/main.py +++ b/routes/main.py @@ -18,6 +18,7 @@ import json import smtplib import requests from functools import wraps +import socket # Set up logging to show in console logging.basicConfig( @@ -1681,4 +1682,40 @@ def init_routes(main_bp): flash('This page is only available in master instances.', 'error') return redirect(url_for('main.dashboard')) - return render_template('main/launch_progress.html') \ No newline at end of file + # Get NGINX settings + nginx_settings = KeyValueSettings.get_value('nginx_settings') + + return render_template('main/launch_progress.html', nginx_settings=nginx_settings) + + @main_bp.route('/api/check-dns', methods=['POST']) + @login_required + @require_password_change + def check_dns(): + if not os.environ.get('MASTER', 'false').lower() == 'true': + return jsonify({'error': 'Unauthorized'}), 403 + + data = request.get_json() + if not data or 'domains' not in data: + return jsonify({'error': 'No domains provided'}), 400 + + domains = data['domains'] + results = {} + + for domain in domains: + try: + # Try to resolve the domain + ip_address = socket.gethostbyname(domain) + results[domain] = { + 'resolved': True, + 'ip': ip_address + } + except socket.gaierror: + results[domain] = { + 'resolved': False, + 'error': 'No DNS record found' + } + + return jsonify({ + 'success': True, + 'results': results + }) \ No newline at end of file diff --git a/templates/main/launch_progress.html b/templates/main/launch_progress.html index 86942be..30b7688 100644 --- a/templates/main/launch_progress.html +++ b/templates/main/launch_progress.html @@ -30,54 +30,8 @@ style="width: 0%">0% -
-
-
-
-
Cloning Repository
-

Waiting...

-
-
- -
-
-
-
Creating Container
-

Waiting...

-
-
- -
-
-
-
Configuring Network
-

Waiting...

-
-
- -
-
-
-
Setting Up Database
-

Waiting...

-
-
- -
-
-
-
Applying Customization
-

Waiting...

-
-
- -
-
-
-
Finalizing Setup
-

Waiting...

-
-
+
+
@@ -96,10 +50,6 @@