batman dev
This commit is contained in:
parent
a4ce8a291d
commit
de000c7ac6
10 changed files with 389 additions and 34 deletions
88
app.py
88
app.py
|
@ -1,33 +1,83 @@
|
|||
from flask import Flask, render_template, request, jsonify
|
||||
from flask import Flask, render_template, request, jsonify, abort
|
||||
import requests
|
||||
import threading
|
||||
import secrets
|
||||
import os
|
||||
import hashlib
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# Generate a secure API key if not already set in environment
|
||||
if not os.environ.get('CADDYDB_API_KEY'):
|
||||
app.config['API_KEY'] = os.environ.get('CADDYDB_API_KEY', secrets.token_hex(32))
|
||||
print(f"API Key: {app.config['API_KEY']} - Store this securely!")
|
||||
else:
|
||||
app.config['API_KEY'] = os.environ.get('CADDYDB_API_KEY')
|
||||
|
||||
proxy_data = {}
|
||||
deleted_servers = set()
|
||||
|
||||
# Authentication decorator
|
||||
def require_api_key(f):
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
api_key = request.headers.get('X-API-Key')
|
||||
if not api_key or api_key != app.config['API_KEY']:
|
||||
return jsonify({"error": "Unauthorized access"}), 401
|
||||
return f(*args, **kwargs)
|
||||
return decorated_function
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
filtered_data = {k: v for k, v in proxy_data.items() if k not in deleted_servers}
|
||||
return render_template('index.html', proxies=filtered_data)
|
||||
|
||||
@app.route('/update', methods=['POST'])
|
||||
def update():
|
||||
@app.route('/api/update', methods=['POST'])
|
||||
@require_api_key
|
||||
def api_update():
|
||||
data = request.json
|
||||
if not data or "server" not in data or "entries" not in data:
|
||||
return jsonify({"error": "Invalid data"}), 400
|
||||
|
||||
|
||||
server_name = data["server"]
|
||||
proxy_data[server_name] = data["entries"]
|
||||
source_type = data.get("source_type", "caddy") # Default to caddy if not specified
|
||||
|
||||
proxy_data[server_name] = {
|
||||
"entries": data["entries"],
|
||||
"source_type": source_type,
|
||||
"last_updated": time.time()
|
||||
}
|
||||
|
||||
if server_name in deleted_servers:
|
||||
deleted_servers.remove(server_name)
|
||||
|
||||
return jsonify({"message": "Updated successfully"}), 200
|
||||
|
||||
@app.route('/delete', methods=['POST'])
|
||||
def delete_entry():
|
||||
# Legacy endpoint for backward compatibility
|
||||
@app.route('/update', methods=['POST'])
|
||||
@require_api_key
|
||||
def update():
|
||||
data = request.json
|
||||
if not data or "server" not in data or "entries" not in data:
|
||||
return jsonify({"error": "Invalid data"}), 400
|
||||
|
||||
server_name = data["server"]
|
||||
proxy_data[server_name] = {
|
||||
"entries": data["entries"],
|
||||
"source_type": "caddy",
|
||||
"last_updated": time.time()
|
||||
}
|
||||
|
||||
if server_name in deleted_servers:
|
||||
deleted_servers.remove(server_name)
|
||||
|
||||
return jsonify({"message": "Updated successfully"}), 200
|
||||
|
||||
@app.route('/api/delete', methods=['POST'])
|
||||
@require_api_key
|
||||
def api_delete_entry():
|
||||
data = request.json
|
||||
server_name = data.get("server")
|
||||
if not server_name or server_name not in proxy_data:
|
||||
|
@ -36,8 +86,14 @@ def delete_entry():
|
|||
deleted_servers.add(server_name)
|
||||
return jsonify({"message": f"Server {server_name} deleted"}), 200
|
||||
|
||||
@app.route('/status/<domain>')
|
||||
def check_status(domain):
|
||||
# Legacy endpoint for backward compatibility
|
||||
@app.route('/delete', methods=['POST'])
|
||||
@require_api_key
|
||||
def delete_entry():
|
||||
return api_delete_entry()
|
||||
|
||||
@app.route('/api/status/<domain>')
|
||||
def api_check_status(domain):
|
||||
"""Check if a subdomain is reachable"""
|
||||
try:
|
||||
response = requests.get(f"https://{domain}", timeout=3)
|
||||
|
@ -45,5 +101,17 @@ def check_status(domain):
|
|||
except requests.exceptions.RequestException:
|
||||
return jsonify({"status": "offline"})
|
||||
|
||||
# Legacy endpoint for backward compatibility
|
||||
@app.route('/status/<domain>')
|
||||
def check_status(domain):
|
||||
return api_check_status(domain)
|
||||
|
||||
@app.route('/api/servers', methods=['GET'])
|
||||
@require_api_key
|
||||
def list_servers():
|
||||
"""List all registered servers"""
|
||||
filtered_data = {k: v for k, v in proxy_data.items() if k not in deleted_servers}
|
||||
return jsonify({"servers": list(filtered_data.keys())}), 200
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5000)
|
||||
app.run(host='0.0.0.0', port=5000, ssl_context='adhoc') # Using adhoc SSL for development
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue