from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager from flask_wtf.csrf import CSRFProtect import os from dotenv import load_dotenv import redis load_dotenv() db = SQLAlchemy() login_manager = LoginManager() csrf = CSRFProtect() redis_client = None def create_app(): app = Flask(__name__) # Security configurations app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', os.urandom(32)) app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'sqlite:///finance.db') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max file size app.config['UPLOAD_FOLDER'] = 'app/static/uploads' app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'pdf', 'gif'} # Security headers @app.after_request def set_security_headers(response): response.headers['X-Content-Type-Options'] = 'nosniff' response.headers['X-Frame-Options'] = 'DENY' response.headers['X-XSS-Protection'] = '1; mode=block' response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains' response.headers['Content-Security-Policy'] = "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:;" return response # Initialize extensions db.init_app(app) login_manager.init_app(app) csrf.init_app(app) login_manager.login_view = 'auth.login' login_manager.login_message = 'Please log in to access this page.' # Initialize Redis global redis_client redis_url = os.getenv('REDIS_URL', 'redis://localhost:6369/0') redis_client = redis.from_url(redis_url, decode_responses=True) # Register blueprints from app.routes import auth, main app.register_blueprint(auth.bp) app.register_blueprint(main.bp) # Create tables with app.app_context(): db.create_all() return app