diff --git a/server.py b/server.py index 86a1736..927f6c9 100644 --- a/server.py +++ b/server.py @@ -359,7 +359,11 @@ def setup_shared_routes(app, index_file='index.html'): @app.route('/') def index(): - return send_from_directory('.', index_file) + response = send_from_directory('.', index_file) + response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0' + response.headers['Pragma'] = 'no-cache' + response.headers['Expires'] = '0' + return response @app.route('/upload', methods=['POST']) def upload_file(): @@ -661,19 +665,27 @@ def dj_audio(data): _feed_transcoder(bytes(data)) # === LISTENER SERVER === -listener_app = Flask(__name__, static_folder='.', static_url_path='') +# static_folder=None prevents Flask's built-in static handler from serving +# DJ files (like index.html) at / — all static files go through our +# custom serve_static route which has security checks. +listener_app = Flask(__name__, static_folder=None) listener_app.config['SECRET_KEY'] = CONFIG_SECRET + '_listener' listener_app.config['MAX_CONTENT_LENGTH'] = CONFIG_MAX_UPLOAD_MB * 1024 * 1024 setup_shared_routes(listener_app, index_file='listener.html') -# Block write/admin endpoints on the listener server +# Block write/admin endpoints AND DJ-only files on the listener server @listener_app.before_request def _restrict_listener_routes(): - """Prevent listeners from accessing DJ-only write endpoints.""" + """Prevent listeners from accessing DJ-only endpoints and files.""" blocked_paths = ('/update_settings', '/upload', '/save_keymaps', '/browse_directories') if request.path in blocked_paths: from flask import abort abort(403) + # Block DJ-only files — prevents serving the DJ panel even via direct URL + dj_only_files = ('/index.html', '/script.js', '/style.css') + if request.path in dj_only_files: + from flask import abort + abort(403) listener_socketio = SocketIO( listener_app, cors_allowed_origins=CONFIG_CORS,