diff --git a/app.py b/app.py index 22984a9..a26fd14 100644 --- a/app.py +++ b/app.py @@ -81,7 +81,6 @@ talisman_kwargs = { "content_security_policy": csp_policy, "x_content_type_options": app.config.get("ENABLE_XCTO", True), "strict_transport_security_include_subdomains": False, - "session_cookie_secure": app.config.get("SESSION_COOKIE_SECURE", False), } referrer_policy = app.config.get("REFERRER_POLICY") @@ -91,18 +90,17 @@ if referrer_policy: talisman = Talisman(app, **talisman_kwargs) register_heif_opener() # pillow_heif dla HEIC - -ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "webp", "heic"} SQLALCHEMY_ECHO = True +ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "webp", "heic"} -SYSTEM_PASSWORD = app.config.get("SYSTEM_PASSWORD", "changeme") -DEFAULT_ADMIN_USERNAME = app.config.get("DEFAULT_ADMIN_USERNAME", "admin") -DEFAULT_ADMIN_PASSWORD = app.config.get("DEFAULT_ADMIN_PASSWORD", "admin123") -UPLOAD_FOLDER = app.config.get("UPLOAD_FOLDER", "uploads") -AUTHORIZED_COOKIE_VALUE = app.config.get("AUTHORIZED_COOKIE_VALUE", "80d31cdfe63539c9") -AUTH_COOKIE_MAX_AGE = app.config.get("AUTH_COOKIE_MAX_AGE", 86400) -HEALTHCHECK_TOKEN = app.config.get("HEALTHCHECK_TOKEN", "alamapsaikota1234") -SESSION_TIMEOUT_MINUTES = int(app.config.get("SESSION_TIMEOUT_MINUTES", 10080)) +SYSTEM_PASSWORD = app.config.get("SYSTEM_PASSWORD") +DEFAULT_ADMIN_USERNAME = app.config.get("DEFAULT_ADMIN_USERNAME") +DEFAULT_ADMIN_PASSWORD = app.config.get("DEFAULT_ADMIN_PASSWORD") +UPLOAD_FOLDER = app.config.get("UPLOAD_FOLDER") +AUTHORIZED_COOKIE_VALUE = app.config.get("AUTHORIZED_COOKIE_VALUE") +AUTH_COOKIE_MAX_AGE = app.config.get("AUTH_COOKIE_MAX_AGE") +HEALTHCHECK_TOKEN = app.config.get("HEALTHCHECK_TOKEN") +SESSION_TIMEOUT_MINUTES = int(app.config.get("SESSION_TIMEOUT_MINUTES")) SESSION_COOKIE_SECURE = app.config.get("SESSION_COOKIE_SECURE") app.config["COMPRESS_ALGORITHM"] = ["zstd", "br", "gzip", "deflate"] @@ -259,8 +257,10 @@ if app.config["SQLALCHEMY_DATABASE_URI"].startswith("sqlite:///"): with app.app_context(): - admin_username = app.config.get("DEFAULT_ADMIN_USERNAME", "admin") - admin_password = app.config.get("DEFAULT_ADMIN_PASSWORD", "admin123") + db.create_all() + + admin_username = DEFAULT_ADMIN_USERNAME + admin_password = DEFAULT_ADMIN_PASSWORD password_hash = hash_password(admin_password) # Szukamy użytkownika o loginie "admin" @@ -270,16 +270,18 @@ with app.app_context(): if not admin.is_admin: admin.is_admin = True # Ustaw admina jeśli był user ale nie admin if not check_password(admin.password_hash, admin_password): - admin.password_hash = password_hash # Ewentualna zmiana hasła + admin.password_hash = password_hash + print(f"[INFO] Zmieniono hasło admina '{admin_username}' z konfiguracji.") db.session.commit() else: # Tworzymy tylko jeśli NIE istnieje taki username! - admin = User(username=admin_username, password_hash=password_hash, is_admin=True) + admin = User( + username=admin_username, password_hash=password_hash, is_admin=True + ) db.session.add(admin) db.session.commit() - @static_bp.route("/static/js/") def serve_js(filename): response = send_from_directory("static/js", filename) @@ -323,7 +325,6 @@ def serve_css_lib(filename): app.register_blueprint(static_bp) - def allowed_file(filename): return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS @@ -2869,48 +2870,26 @@ def handle_unmark_not_purchased(data): emit("item_unmarked_not_purchased", {"item_id": item.id}, to=str(item.list_id)) -@app.cli.command("create_db") +@app.cli.command("db_info") def create_db(): - inspector = inspect(db.engine) - expected_tables = set(db.Model.metadata.tables.keys()) - actual_tables = set(inspector.get_table_names()) - missing_tables = expected_tables - actual_tables - extra_tables = actual_tables - expected_tables + with app.app_context(): + inspector = inspect(db.engine) + actual_tables = inspector.get_table_names() - if missing_tables: - print(f"Brakuje tabel: {', '.join(sorted(missing_tables))}") + table_count = len(actual_tables) + record_total = 0 + with db.engine.connect() as conn: + for table in actual_tables: + try: + count = conn.execute(text(f"SELECT COUNT(*) FROM {table}")).scalar() + record_total += count + except Exception: + pass - if extra_tables: - print(f"Dodatkowe tabele w bazie: {', '.join(sorted(extra_tables))}") - - critical_error = False - - for table in expected_tables & actual_tables: - expected_columns = set(c.name for c in db.Model.metadata.tables[table].columns) - actual_columns = set(c["name"] for c in inspector.get_columns(table)) - missing_cols = expected_columns - actual_columns - extra_cols = actual_columns - expected_columns - - if missing_cols: - print( - f"Brakuje kolumn w tabeli '{table}': {', '.join(sorted(missing_cols))}" - ) - critical_error = True - - if extra_cols: - print( - f"Dodatkowe kolumny w tabeli '{table}': {', '.join(sorted(extra_cols))}" - ) - - if missing_tables or critical_error: - print("Struktura bazy jest niekompletna lub niezgodna. Przerwano.") - return - - if not actual_tables: - db.create_all() - print("Utworzono strukturę bazy danych.") - else: - print("Struktura bazy danych jest poprawna.") + print("\nStruktura bazy danych jest poprawna.") + print(f"Silnik: {db.engine.name}") + print(f"Liczba tabel: {table_count}") + print(f"Łączna liczba rekordów: {record_total}") if __name__ == "__main__": diff --git a/config.py b/config.py index 815ba57..2419e97 100644 --- a/config.py +++ b/config.py @@ -1,12 +1,16 @@ import os + basedir = os.path.abspath(os.path.dirname(__file__)) + class Config: SECRET_KEY = os.environ.get("SECRET_KEY", "D8pceNZ8q%YR7^7F&9wAC2") DB_ENGINE = os.environ.get("DB_ENGINE", "sqlite").lower() if DB_ENGINE == "sqlite": - SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(basedir, 'database', 'shopping.db')}" + SQLALCHEMY_DATABASE_URI = ( + f"sqlite:///{os.path.join(basedir, 'db', 'shopping.db')}" + ) elif DB_ENGINE == "pgsql": SQLALCHEMY_DATABASE_URI = f"postgresql://{os.environ['DB_USER']}:{os.environ['DB_PASSWORD']}@{os.environ['DB_HOST']}:{os.environ.get('DB_PORT', 5432)}/{os.environ['DB_NAME']}" elif DB_ENGINE == "mysql": @@ -20,17 +24,23 @@ class Config: DEFAULT_ADMIN_PASSWORD = os.environ.get("DEFAULT_ADMIN_PASSWORD", "admin123") UPLOAD_FOLDER = os.environ.get("UPLOAD_FOLDER", "uploads") AUTHORIZED_COOKIE_VALUE = os.environ.get("AUTHORIZED_COOKIE_VALUE", "cookievalue") + BCRYPT_PEPPER = os.environ.get("BCRYPT_PEPPER", "sekretnyKluczBcrypt") + SESSION_COOKIE_SECURE = os.environ.get("SESSION_COOKIE_SECURE", "0") == "1" + HEALTHCHECK_TOKEN = os.environ.get("HEALTHCHECK_TOKEN", "alamapsaikota1234") + try: - AUTH_COOKIE_MAX_AGE = int(os.environ.get("AUTH_COOKIE_MAX_AGE", "86400") or "86400") + AUTH_COOKIE_MAX_AGE = int( + os.environ.get("AUTH_COOKIE_MAX_AGE", "86400") or "86400" + ) except ValueError: AUTH_COOKIE_MAX_AGE = 86400 - HEALTHCHECK_TOKEN = os.environ.get("HEALTHCHECK_TOKEN", "alamapsaikota1234") try: - SESSION_TIMEOUT_MINUTES = int(os.environ.get("SESSION_TIMEOUT_MINUTES", "10080") or "10080") + SESSION_TIMEOUT_MINUTES = int( + os.environ.get("SESSION_TIMEOUT_MINUTES", "10080") or "10080" + ) except ValueError: SESSION_TIMEOUT_MINUTES = 10080 - SESSION_COOKIE_SECURE = os.environ.get("SESSION_COOKIE_SECURE", "0") == "1" ENABLE_HSTS = os.environ.get("ENABLE_HSTS", "0") == "1" ENABLE_XFO = os.environ.get("ENABLE_XFO", "0") == "1" @@ -41,11 +51,19 @@ class Config: DEBUG_MODE = os.environ.get("DEBUG_MODE", "1") == "1" DISABLE_ROBOTS = os.environ.get("DISABLE_ROBOTS", "0") == "1" - JS_CACHE_CONTROL = os.environ.get("JS_CACHE_CONTROL", "no-cache, no-store, must-revalidate") - CSS_CACHE_CONTROL = os.environ.get("CSS_CACHE_CONTROL", "public, max-age=3600") - LIB_JS_CACHE_CONTROL = os.environ.get("LIB_JS_CACHE_CONTROL", "public, max-age=604800") - LIB_CSS_CACHE_CONTROL = os.environ.get("LIB_CSS_CACHE_CONTROL", "public, max-age=604800") - UPLOADS_CACHE_CONTROL = os.environ.get("UPLOADS_CACHE_CONTROL", "public, max-age=2592000, immutable") - - BCRYPT_PEPPER = os.environ.get("BCRYPT_PEPPER", "sekretnyKluczBcrypt") + JS_CACHE_CONTROL = os.environ.get( + "JS_CACHE_CONTROL", "no-cache, no-store, must-revalidate" + ) + CSS_CACHE_CONTROL = os.environ.get( + "CSS_CACHE_CONTROL", "public, max-age=3600" + ) + LIB_JS_CACHE_CONTROL = os.environ.get( + "LIB_JS_CACHE_CONTROL", "public, max-age=604800" + ) + LIB_CSS_CACHE_CONTROL = os.environ.get( + "LIB_CSS_CACHE_CONTROL", "public, max-age=604800" + ) + UPLOADS_CACHE_CONTROL = os.environ.get( + "UPLOADS_CACHE_CONTROL", "public, max-age=2592000, immutable" + ) diff --git a/entrypoint.sh b/entrypoint.sh index d2c9f92..505dc84 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,3 +1,3 @@ #!/bin/sh -flask db upgrade 2>/dev/null || flask create_db +flask db upgrade 2>/dev/null || flask db_info exec python app.py