Move client key to database with admin UI for key management and QR code generation

- Store client key in SQLite database instead of environment variable
- Add database migration from CLIENT_KEY environment variable to preserve existing keys
- Add admin UI with tabbed interface (Configuration and QR Code tabs)
- Implement QR code generation containing server config (address, port, key) for Android app
- Add functionality to regenerate client key with warning dialog
- Add buttons to download QR code as PNG and copy QR image to clipboard
- Add manual input fields for server address and port configuration
- Update requirements.txt with pyotp and qrcode dependencies
This commit is contained in:
2025-12-27 14:29:58 -05:00
parent 872ae74668
commit 164e2162a2
7 changed files with 786 additions and 32 deletions

View File

@@ -10,14 +10,14 @@ from controllers.file_controller import (
cleanup_expired_files, cleanup_abandoned_uploads
)
from controllers.admin_controller import (
setup_admin, setup_admin_totp, admin_login, admin_dashboard, admin_logout
setup_admin, setup_admin_totp, admin_login, admin_dashboard, admin_logout,
update_config, regenerate_key
)
from views import views
from models import init_db, migrate_from_json
from models import init_db, migrate_from_json, migrate_client_key_to_db
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'tmp/uploads'
app.config['CLIENT_KEY'] = os.environ.get('CLIENT_KEY', 'default-secret-key')
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', os.urandom(24).hex())
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=24)
@@ -28,6 +28,7 @@ if not os.path.exists(app.config['UPLOAD_FOLDER']):
log.i("Initializing database...")
init_db()
migrate_from_json()
migrate_client_key_to_db()
# Run cleanup on startup
cleanup_expired_files()
@@ -40,12 +41,19 @@ def require_client_key(f):
if not client_key:
log.e("No client key provided in request headers")
return jsonify({'error': 'Missing client key'}), 401
expected_key = app.config['CLIENT_KEY']
# Get expected key from database
from models import get_client_key
expected_key = get_client_key()
if not expected_key:
log.e("Server configuration error: no client key in database")
return jsonify({'error': 'Server configuration error'}), 500
if client_key != expected_key:
log.e(f"Invalid client key provided. Expected length: {len(expected_key)}, Got length: {len(client_key)}")
return jsonify({'error': 'Invalid client key'}), 401
log.i("Client key authentication successful")
return f(*args, **kwargs)
return decorated_function
@@ -71,6 +79,8 @@ app.route('/admin/setup/totp', methods=['GET', 'POST'], endpoint='setup_admin_to
app.route('/admin/login', methods=['GET', 'POST'], endpoint='admin_login')(admin_login)
app.route('/admin', methods=['GET'], endpoint='admin_dashboard')(admin_dashboard)
app.route('/admin/logout', methods=['GET'], endpoint='admin_logout')(admin_logout)
app.route('/admin/config', methods=['POST'], endpoint='update_config')(update_config)
app.route('/admin/regenerate-key', methods=['POST'], endpoint='regenerate_key')(regenerate_key)
# Register frontend views
app.register_blueprint(views)